0

I need to make a program that will emulate the terminal of Linux. Since some system calls requires 1,2 or more arguments, I want to make sure that the number of parameters given are correct. I'm using strtok() to separate the call name from the arguments, but I need to know how many tokens strtok() created to compare it.

Here's and example code:

char *comand = (char*) malloc(sizeof(char)*100);
char *token;
char *path1 = (char*) malloc(sizeof(char)*100);
char *path2= (char*) malloc(sizeof(char)*100);



    fgets(comand, 100, stdin);

    printf( "\nYou entered: %s \n", comand);

    token = strtok(comand ," ");

    //Check the number of tokens and add a condition in each IF to match

    if (strcmp("ls",token) == 0) {
        token = strtok(NULL," ");
        strcpy(path1,token);

    }
    else if (strcmp("cat",token) == 0) {
        token = strtok(NULL," ");
        strcpy(path1,token);

    }
    else if (strcmp("cp",token) == 0) {
        token = strtok(NULL," ");
        strcpy(path1,token);
        token = strtok(NULL," ");
        strcpy(path2,token);

    }
    else if (strcmp("mv",token) == 0) {
        token = strtok(NULL," ");
        strcpy(path1,token);
        token = strtok(NULL," ");
        strcpy(path2,token);    

    }
    else if (strcmp("find",token) == 0) {
        token = strtok(NULL," ");
        strcpy(path1,token);

    }
    else if (strcmp("rm",token) == 0) {
        token = strtok(NULL," ");
        strcpy(path1,token);

    }
    else if (strcmp("mkdir",token) == 0) {
        token = strtok(NULL," ");
        strcpy(path1,token);
    }
    else if (strcmp("rmdir",token) == 0) {
        token = strtok(NULL," ");
        strcpy(path1,token);
    }
    else if (strcmp("quit",token) == 0) {
        exit(0);
    }
    else print("Number of parameters do not match);
tony
  • 49
  • 1
  • 10
  • 1
    "System calls"? From the console? – EOF Nov 17 '14 at 21:54
  • No, the "System calls" of this "Terminal" are procedures made in language C, not the Unix ones. If the command is "ls", then I would call a procedure named "commLs" or something like that, and pass it the tokens. – tony Nov 17 '14 at 22:02
  • You might also want to check this question: http://stackoverflow.com/questions/13078926/is-there-a-way-to-count-tokens-in-c – Henrik Carlqvist Nov 17 '14 at 22:19
  • What will you do about quotation marks? – Dmitri Nov 17 '14 at 22:20

2 Answers2

0

the only thing strtok() does is look for the next occurance of the delimiter and overwrite that character with a \0 and return the pointer with the offset added. the pointer is kept in a static variable that's why a subsequent call to it with a NULL for the char * will perform it on the last string used from the offset that the last delimiter was found.

this page has a very nice example: http://en.cppreference.com/w/c/string/byte/strtok

If you only want to count the arguments it would be easier to use strchr(), this function searches for a character and returns a pointer to its location. you could use it like this.

unsigned int i = 0;
char *temp = token;
while ( (temp = strchr(temp, '') != NULL) ) {
    ++i;
}

this has the added benefit of not modifying your original char array while strtok() does!

I would handle this within the functions you create for each command.

you pass all options to the function and there you parse it. either with strtok() or whatever else you want to use.

This keeps it nice and clean within the sub-routines and you will always know what to expect.

if (strcmp("ls",token) == 0) {
    token = strtok(NULL," ");
    strcpy(path1,token);      // I would maybe change the path variable name to args
    ret = lscmd(path1);
    if (ret == -1) {
         // invalid input detected
    }  
}

then you would have a ls function

int lsdcmd(char *args) {
    // parse args for argumants you are looking for, return -1 if it fails

    // do whatever you want to do.
}
rowan.G
  • 717
  • 7
  • 13
0

You can count the arguments using strtok this way:

Example:

const char* delimiter = ",";
char* tokens[MAX_NUM_OF_ARGS];

unsigned int index = 0;
char* temp = strtok(buff,delimiter);
while (temp!=NULL){
    if(index<MAX_NUM_OF_ARGS){
        tokens[index]=temp;
    }
    index++;
    temp = strtok(NULL,delimiter);
}

Then later you can iterate through the array of pointers (tokens) and compare them...

Paulo Silva
  • 159
  • 1
  • 3