[英]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;
因为*argv
是char *
,而不是字符。 这不是正式的错误; '\\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.