kevin
kevin

Reputation: 306

C - splitting command line arguments by commas

I know that when passing command arguments such as a.out ls -l pwd cat hello.txt that argv[0] is a.out, argv[1] is ls and argv[2] is -l etc etc.

I want to pass command arguments so that they would be separated by commas rather than whitespace so in the command a.out ls -l, pwd, cat hello.txt: argv[1] would be ls -l and argv[2] would be pwd and argv[3] would be cat hello.txt

my current code:

int main (int argc, char* argv[])
{
    int i;
    char str[100] = "";
    char* token;
    for (i = 1; i < argc; i++)
    {
        strcat(strcat(str, " "),argv[i]); // stores arguments in a string
        token = strtok (argv[i], ", "); // seperates arguments  by comma 
        printf("%s\n",token);
    }
    return 0;
}

its output:

ls
-a
pwd
cat
hello.txt

if I did it correctly output should be:

ls -a
pwd
cat hello.txt

Upvotes: 0

Views: 1970

Answers (2)

int main(int argc, char* argv[]) 
{
    int i;
    char str[100] = "";
    
    for (i = 1; i < argc; i++)
    {
        strcat(strcat(str, " "), argv[i]); // stores arguments in a string
        
        if (str[strlen(str)-1] == ',') {
            str[strlen(str)-1] = '\0'; // remove comma at the end
            printf("%s\n", str);       // do something with your token
            str[0] = '\0';             // reset str buf
        }
    }
    
    printf("%s\n", str); // do something with the remaining token

    return 0;
}

A version without strtok.

Note: If your argument list does not contain any commas, you will get the list as a whole string (not separated by 'space').

Upvotes: 1

user13395631
user13395631

Reputation:

your token variable is just an array of characters, you need a double pointer in order to store each token for each argument. something like char [10][1000] buffer would work up to 10 arguments.

something like this should work:

typedef struct{
    char rawCmd[9999];
    char *cmd;
    char *argv[9999];
} Command;

Command parsecommand(char *rawCommand, Command c){ 
    int i = 0;
    memset(c.rawCmd, 0, sizeof(c.rawCmd));
    strcat(c.rawCmd, rawCommand); // setting the whole thing to the structs rawCmd field just in case i need the whole thing
    char *ptr = strtok(rawCommand, " ");
    c.cmd = ptr; // gets the base cmd
    while (ptr != NULL)
    { // every element after the first will be an arg (if there are any!) 
        c.argv[i++] = ptr;
        ptr = strtok(NULL, " ");
    }
    c.argv[i++] = NULL;
    return c;
}
int main(int argc, char *argv[]){
    int i, iCommandCount = 0, iExitStatus = 0;  
    char cmd[6][9999], cur[9999]; 
    Command commands[6], c; 
    memset(&cur[0], 0, sizeof(cur));
    memset(&cmd[0], 0, sizeof(cmd));

    // seperates commands 
    for (i = 1; i < argc; i++){
        if (strcmp(argv[i], ",") != 0){
            strcat(cur, argv[i]);
            strcat(cur, " ");
        }
        if (strcmp(argv[i], ",") == 0 || i + 1 == argc){
            strcat(cmd[iCommandCount++], cur); 
            memset(&cur, 0, sizeof(cur));
        }
    }

    // splits commands by comma
    for (i = 0; i < iCommandCount; i++)
    {
        commands[i] = parsecommand(cmd[i], c);
        printf("commands: %s\n", commands[i].cmd);
    }

    return 0;
}

output:

 a.out ls -l ,  pwd
commands: ls
commands: pwd

Upvotes: 0

Related Questions