【问题标题】:C - splitting command line arguments by commasC - 用逗号分割命令行参数
【发布时间】:2021-03-13 23:53:30
【问题描述】:

我知道在传递命令参数时,例如a.out ls -l pwd cat hello.txt ,argv[0] 是a.out,argv[1] 是ls,argv[2] 是-l 等等。

我想传递命令参数,以便它们用逗号而不是空格分隔 所以在命令a.out ls -l, pwd, cat hello.txt:argv[1] 将是ls -l 和argv[2] 将是pwd 和argv[3] 将是cat hello.txt

我当前的代码:

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;
}

它的输出:

ls
-a
pwd
cat
hello.txt

如果我做得正确,输出应该是:

ls -a
pwd
cat hello.txt

【问题讨论】:

  • 如果您需要其中包含空格的内容作为参数,请用引号将其括起来。添加逗号不会改变命令行在您的程序看到之前的解析方式。
  • 它应该可以带引号或不带引号

标签: c string command-line arguments command-line-arguments


【解决方案1】:

您的 token 变量只是一个字符数组,您需要一个双指针来存储每个参数的每个标记。像 char [10][1000] buffer 这样的东西最多可以处理 10 个参数。

这样的事情应该可以工作:

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;
}

输出:

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

【讨论】:

  • 似乎有效,但它没有打印出谁 ls -l? 只是 ls,但没关系,因为它仍然以逗号分隔,这是我非常想要的
【解决方案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;
}

没有strtok的版本。

注意:如果你的参数列表不包含任何逗号,你会得到一个完整的字符串列表(不被“空格”分隔)。

【讨论】:

  • 它不会打印最后一个参数,除非我在循环完成后放置 print 语句,我可以通过什么方式让 for 循环内的 print 语句也打印最后一个参数?
  • @sjw037 嗯,循环的逻辑是将参数连接到一个字符串,直到检测到逗号。这就是为什么我们需要循环之外的最后一个打印,因为最后没有逗号。您还可以检查您是否在最后一个参数,如果是,则打印剩余的令牌。
猜你喜欢
  • 1970-01-01
  • 2023-03-03
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多