在以下程序中:
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
char *delivery = "";
int thick = 0;
int count = 0;
char ch;
for (int i = 0; i < argc; i++) {
fprintf(stdout, "Argv[%i] = %s\n", i, argv[i]); /* printing to understand (ptu) */
}
while ((ch = getopt(argc, argv, "d:t")) != -1)
switch (ch) {
case 'd':
fprintf(stdout, "Optind in case 'd': %i\n", optind);
delivery = optarg;
break;
case 't':
fprintf(stdout, "Optind in case 't': %i\n", optind);
thick = 1;
break;
default:
fprintf(stderr, "Unknown option: '%s'\n", optarg);
return 1;
}
fprintf(stdout, "Argc: %i\n", argc); /* ptu */
fprintf(stdout, "Argv: %p\n", argv); /* ptu */
argc -= optind;
argv += optind;
fprintf(stdout, "Optind: %i. Argc after subtraction: %i, Argv after increment: %p\n", optind, argc, argv);
if (thick)
fprintf(stdout, "Thick crust!\n");
if (delivery[0])
fprintf(stdout, "To be delivered %s\n", delivery);
fprintf(stdout, "Ingredients:\n");
for (count = 0; count < argc; count++)
fprintf(stdout, "%s\n", argv[count]);
return 0;
}
当我使用下面显示的参数运行上述程序时,我得到以下输出:[u@h c]$ ./prog -t -d yesterday anchovies goatcheese pepperoni
Argv[0] = ./prog
Argv[1] = -t
Argv[2] = -d
Argv[3] = yesterday
Argv[4] = anchovies
Argv[5] = goatcheese
Argv[6] = pepperoni
Optind in case 't': 2
Optind in case 'd': 4
Argc: 7
Argv: 0x7ffebee8e498
Optind: 4. Argc after subtraction: 3, Argv index: 0x7ffebee8e4b8
Thick crust!
To be delivered yesterday
Ingredients:
anchovies
goatcheese
pepperoni
我想知道我对幕后发生的事情的理解是否准确,特别是对于程序中的参数解析步骤。很抱歉没有分享一个更小的代表,但在这种情况下我可能不能。如果我能把这个展示给理解 C 的 friend ,我就不会向 stackoverflow 发送垃圾邮件。所以,请多多包涵。这里什么都没有:optstring "d:t"
中的下一个匹配字符。到字符变量ch
, 直到它用完选项(没有双关语),这就是它返回 -1
的时间。并且控件将退出while循环。optind
(大概是从 1 开始,因为 argv[0] 是程序名称)将递增以包含 argv 中要处理的下一个元素的索引...所以在 case 't', optind = <index of "-d" i.e. 2>
,并在 case 'd', optind = <index of "anchovies" i.e. 4>
(这是因为 getopt()
从 :
中的“d
”之后的“optstring
”实现,-d
后面将跟随其 optarg
在命令行上,因此 optind
递增为这里是“4”而不是“3”)-t
之后和 -d yesterday
正在处理 getopt()
在 argv[]
中找不到其他内容匹配 optstring
中的元素;因此它返回 -1
我们跳出while循环。 optind
仍然设置为 4,因为 getopt 在 optstring 中的“-d”之后没有找到任何其他内容。 optind
的值“4”来自 argc
以确保我们跳过 option arguments
(我们已经解析)到剩下的三个 non-option
论据。我们还增加 argv
— 最初指向 argv[0]
的内存位置即"./prog"
——作者 <optind * sizeof(char pointer on a 64-bit machine); i.e. 4 * 8>
这就是为什么 argv 现在在内存中指向 32 个字节:0x7ffebee8e4b8 - 0x7ffebee8e498 == 0x20
.换句话说,argv[0] 指向“anchovies”thick
的值打印内容, delivery
并循环遍历剩余的非选项参数以打印它们......最佳答案
是的,你的理解是正确的。
我会提供两个注意事项:
""
之间的字符。分隔符。 “常量 block ”不是标准概念,但我想您的意思是从二进制文件加载的只读内存块,因为这是字符串文字通常所在的位置。 argv
的字符串指向的指针不是这种;它们不可能,因为在创建二进制文件时不知道它们。相反,它们位于某个未指定的内存区域中,如果您愿意,您可以就地修改它们(尽管这可能会使您的代码困惑);例如argv[0][3] = 'x'
将是合法的。 (C17 标准 5.1.2.2.1 (2))。argc
的值令人困惑。和 argv
在 main
内,并建议您将修改后的值分配给其他一些变量:int remaining_argc = argc - optind;
char **remaining_argv = argv + optind;
关于c - 我对这个 C 程序如何工作的理解正确吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64092854/