c - 我对这个 C 程序如何工作的理解正确吗?

标签 c argv getopt argc

在以下程序中:

#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 发送垃圾邮件。所以,请多多包涵。这里什么都没有:
  • 定义 main 以接受命令行 (cl) 参数。这需要两个参数:
  • 整数 argc 将包含 cl 参数的数量,包括程序的名称,在本例中为 7
  • 字符串数组(即 char 指针数组),其中每个元素将指向作为 cl 参数传递给程序的每个字符串文字(存储在 CONSTANT 内存块中)的第一个元素的内存地址。

  • for 循环(不言自明)
  • 在 while 循环的每次运行中,getopt() 将解析 argv[] 数组并分配 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 的值令人困惑。和 argvmain 内,并建议您将修改后的值分配给其他一些变量:
  • int remaining_argc = argc - optind;
    char **remaining_argv = argv + optind;
    

    关于c - 我对这个 C 程序如何工作的理解正确吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64092854/

    相关文章:

    c - 使用数组指针会产生错误

    c - 如何选择要打开的文件?

    c - 数字生成器未在 C 中打印出预期的第一个数字

    c++ - 我可以在 C++ 中使用 getopt 来读取带参数和不带参数的字符吗?

    c - 使用 getopt 向命令行选项提供两个参数

    c - 在 LLVM 中内联来自不同文件的代码

    c - 从函数中的 argv 分配指针

    c++ - 如何测试 argc 然后将默认值分配给 argv[1]?

    c++ - *argv[] 的解引用值不准确

    c - C 中带有 char*const* 指针的函数 getopt