繁体   English   中英

将参数放入char数组中,代码说明

[英]Putting arguments into a char array, code explanation

我真的想知道下面一段代码中发生了什么。 在函数解析中, *line++ = '\\0'; 意思? 它等于line[i] = '\\0'i++;

接下来,这是什么*argv++ = line; 在做什么? 它如何分配整个变量行我假设首先是argv [0],然后是argv [1]等? 那会不会太久?

接下来只是跳过线阵直到它到达一个单词。

现在,在解析函数完成后,调用argv和argv *会做什么? 是* argv的第一个参数?

在此先感谢,我真的需要了解:(

void  parse(char *line, char **argv)
{
     while (*line != '\0') {  
          while (*line == ' ' || *line == '\t' || *line == '\n')
               *line++ = '\0';  

          *argv++ = line;      

          while (*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n') 
               line++; 
     }
     *argv = '\0';   
}

在主要:

 char  line[1024];      
 char  *argv[64];    
 while (1) {  
      ....
      gets(line); 
      ...
      parse(line, argv);  

表达式*line++ = '\\0'; 是直截了当的。 正如有些人所说, ++运算符的优先级高于*运算符,因此表达式可以括号为*(line++) = '\\0';

line++运算符求值为line的当前值,然后将该值递增。 *line++因此计算当前line指向的字符。 赋值意味着将空字节'\\0'分配给当前位置,并且line增加超过此位置。 这是一个简写:

*line = '\0';
line++;

在这个问题中,你问:

什么是*line++ = '\\0'; 意思? 它等于line[i] = '\\0'i++;

第一部分已得到解决。 第二部分或多或少准确; 严格地说,它仅适用于i = 0; 首先被赋值(所以i在增量后将是1 ),或者如果你总是使用i来索引line而不改变line本身的值。

注意行*argv = '\\0'; line会更常规地写成*argv = NULL; *argv = 0; 因为*argvchar * ,而不是字符。 这不是正式的错误; '\\0'是一个整数常量零,因此是一个有效的空指针常量,但这样写它是常规的。

在给定的代码中:

void parse(char *line, char **argv)
{
     while (*line != '\0') {
          while (*line == ' ' || *line == '\t' || *line == '\n')
               *line++ = '\0';

没有必要消除领先的空白; line++就足够了。 建议使用isspace()isblank()也很诱人。 我观察到来自gets()输入gets()main()程序中显示并且不应该使用)从不包含换行符,因此换行符测试在此上下文中是多余的。

          *argv++ = line;

          while (*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n')
               line++;
     }
     *argv = '\0';
}

想法是,如果输入行是:

arguments   about   the  meaning of life

然后,您将能够安全地进行以下所有断言:

assert(strcmp(argv[0], "arguments") == 0);
assert(strcmp(argv[1], "about") == 0);
assert(strcmp(argv[2], "the") == 0);
assert(strcmp(argv[3], "meaning") == 0);
assert(strcmp(argv[4], "of") == 0);
assert(strcmp(argv[5], "life") == 0);
assert(argv[6] == 0);

鉴于你正在切断输入行,考虑POSIX strtok_r()函数或微软的strtok_s() (或者,如果最坏的情况发生在strtok() ,或者使用strtok()需要极端的话,可能是明智的。注意 - 例如,调用此函数的代码不能在调用时使用strtok() )。

void parse(char *line, char **argv)
{
    char *token = line;
    char *extra;

    while ((token = strtok_r(token, " \t\n", &extra)) != 0)
    {
        *argv++ = token;
        token = 0;
    }
    *argv = 0;
}

重新设计函数以报告有多少(非空)参数可能也是明智的:

int parse(char *line, char **p_argv)
{
    char *token = line;
    char *extra;
    char **argv = p_argv;

    while ((token = strtok_r(token, " \t\n", &extra)) != 0)
    {
        *argv++ = token;
        token = 0;
    }
    *argv = 0;
    return argv - p_argv;
}

*line++ = '\\0'等于:

*line = '\0';
line++;

它用于null终止字符串,因为它应该在C中。

*argv++ = line用于解析char **argv (指向char数组的指针)中提供的参数的下一个参数。

char * line

意味着你得到一个指向char的指针。 所以让我们明确一点

*line

会得到你的实际角色(这称为解除引用)那么*line++ = '\\0'; 的确是:

*line = '\0';
line++;

所以它与line[i++] = '\\0'

完全相同适用于* argv ++ = line;

请注意 ,* line ++与(* line)++完全不同。

实际上,因为赋值运算符的优先级高于++所以*line++ = '\\0'; 实际上等于:

*line = '\0';
*line++;          // Increment the pointer in sizeof(char)

现在,关于你关于argv的问题,请注意它被定义为一个字符串数组。 *argv的类型是char* ,它匹配行的类型。 赋值*argv++ = line意味着将*argv++ = line指向的地址放置到* argv(而不是行中的字符串的完整副本),因此不存在写入太多内容的风险(除非argv不包含足够的元素来保存行 )。 最后,语句*argv = '\\0'可能用于标记我们刚刚到达字符串数组的末尾,以类似的方式将字符串的结尾标记为C.

++运算符的优先级高于* so

*line++将导致指针line首先被激活。

line++;

然后

*line++ = '\0';

argv在这里是双指针, *argv将指向line

*argv++ = line

与上述相同的解释

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM