如何解决我对该C程序的工作方式的理解正确吗?
在以下程序中:
#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的朋友展示这个消息,那么我就不会出现stackoverflow垃圾邮件。因此,请忍受我。什么都没有:
-
已定义main以接受命令行(cl)参数。这需要两个参数:
- 整数argc,它将包含cl参数的数量,包括程序名称,在这种情况下为7
- 字符串数组(即char指针数组),其每个元素将指向作为cl参数传入程序的每个字符串文字(存储在CONSTANT内存块中)的第一个元素的内存地址。
-
for循环(自我解释)
-
在while循环的每次运行中,getopt()都会解析argv []数组,并将
optstring "d:t"
中的下一个匹配字符分配给字符变量ch
,直到用完为止选项(不需要双关语),它将返回-1
,并且控件将退出while循环。-
在每个这样的遍历
- (由于argv [0]是程序名而在1处开始)将增加,以包含要在argv中处理的下一个元素的索引。
case 't',optind = <index of "-d" i.e. 2>
和case 'd',optind = <index of "anchovies" i.e. 4>
中(这是因为getopt()
从:
的'd
'之后的“optstring
”开始,{{ 1}}后面紧跟着其-d
,因此optarg
在这里增加到“ 4”,而不是“ 3”)
在 -
-d yesterday
在getopt()
中找不到与argv[]
中的元素匹配的其他内容;因此它返回optstring
,我们跳出了while循环。-1
仍设置为4,因为getopt在optstring的'-d之后没有找到其他内容。
optind
中,optind
和-t
处理后, - (由于argv [0]是程序名而在1处开始)将增加,以包含要在argv中处理的下一个元素的索引。
-
我们现在将
optind
的{{1}}的值“ 4”递减,以确保我们跳过optind
(我们已经解析过)到其余三个{{ 1}}参数。我们还将argc
(最初指向option arguments
即non-option
的内存位置增加argv
,这就是为什么argv现在在内存中指向32字节的原因:{{1} }。换句话说,argv [0]指向“凤尾鱼” -
然后我们根据
argv[0]
,"./prog"
的值打印内容,并循环遍历其余的非选项参数以同样打印它们...
解决方法
是的,您的理解是正确的。
我会提供两个注释:
-
“字符串文字”是指在程序中实际定义的字符串,为
""
分隔符之间的字符。 “ CONSTANT块”不是标准概念,但是我想您是指从二进制文件中加载的只读存储器块,因为这通常是字符串文字所在的位置。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;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。