optind 变量在 C 语言中是如何分配的

Jinku Hu 2023年1月30日 2021年3月21日
  1. 使用 getopt 函数解析 C 语言中的命令行选项
  2. 使用 optindoptarg 变量来处理 C 语言中的 argv 元素
optind 变量在 C 语言中是如何分配的

本文将演示有关如何在 C 语言中分配 optind 变量的多种方法。

使用 getopt 函数解析 C 语言中的命令行选项

基于 UNIX 的系统上的典型命令行程序带有参数和选项。选项通常用连字符后面的字符指定,每个唯一字符要么指示有关给定参数的信息,要么产生要执行的程序的特定行为。选项可以具有强制或可选参数。在后一种情况下,程序通常允许在单个连字符后对选项进行分组,并且可能在命令末尾传递唯一参数。

getopt 函数用于解析选项并从程序中检索给定参数,并根据输入执行相应的代码路径。getopt 接受三个参数,其中前两个参数是传递给 main 函数的 argcargv。第三个参数是 optstring-指向表示合法选项字符的字符串的指针。需要连续调用 getopt,直到检索到每个选项为止。

在下面的示例中,我们演示了一个带有 px 字符的选项的程序。注意,optstring 以冒号开头,当遇到缺少的参数时,该值指示 getopt 调用需要返回的值。另外,在字符(例如 p)之后指定的冒号表示该选项需要该参数;两个冒号表示该参数是可选的。可以在命令行上多次传递相同的选项字符。getopt 函数返回选项字符(如果成功的话)或字符 ? 如果遇到的选项字符不在 optstring 中。

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

int main(int argc, char *argv[]) {
    int opt, xnum = 0;
    char *pstr = NULL;

    while ((opt = getopt(argc, argv, ":p:x")) != -1) {
        printf("opt = %3d (%c); optind = %d\n", opt, opt, optind);

        switch (opt) {
            case 'p': pstr = optarg;        break;
            case 'x': xnum++;               break;
            case ':': fprintf(stderr, "Missing argument!\n"
                                      "Usage: %s [-p arg] [-x]\n", argv[0]); exit(EXIT_FAILURE);
            case '?': fprintf(stderr, "Unrecognized option!\n"
                                      "Usage: %s [-p arg] [-x]\n", argv[0]); exit(EXIT_FAILURE);
            default:  fprintf(stderr, "Unexpected case in switch()"); exit(EXIT_FAILURE);
        }
    }

    exit(EXIT_SUCCESS);
}

示例命令:

./program_name -p hello -p there

输出:

opt = 112 (p); optind = 3
opt = 112 (p); optind = 5

使用 optindoptarg 变量来处理 C 语言中的 argv 元素

前面的代码示例演示了典型的 getopt 用法,该函数从 while 循环表达式中调用该函数,直到返回错误代码 -1。同时,switch 语句检查可能的 getopt 返回值以执行相应的代码块。注意,optind 变量表示 argv 中下一个元素的索引,并且在第一次调用 getopt 之前将其初始化为 1。另一方面,optarg 是一个外部变量,它指向当前选项字符后面的参数。如果该选项不包含参数,则将 optarg 设置为零。下一个代码示例显示如何保存 optarg 变量指向的参数,然后根据需要对其进行操作。请注意,参数可以在选项之后而不使用空格分隔符。

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

int main(int argc, char *argv[]) {
    int opt, xnum = 0;
    char *pstr = NULL;

    while ((opt = getopt(argc, argv, ":p:x")) != -1) {
        printf("opt = %3d (%c); optind = %d\n", opt, opt, optind);

        switch (opt) {
            case 'p': pstr = optarg;        break;
            case 'x': xnum++;               break;
            case ':': fprintf(stderr, "Missing argument!\n"
                                      "Usage: %s [-p arg] [-x]\n", argv[0]); exit(EXIT_FAILURE);
            case '?': fprintf(stderr, "Unrecognized option!\n"
                                      "Usage: %s [-p arg] [-x]\n", argv[0]); exit(EXIT_FAILURE);
            default:  fprintf(stderr, "Unexpected case in switch()"); exit(EXIT_FAILURE);
        }
    }

    if (xnum != 0)
        printf("-x was specified (count=%d)\n", xnum);
    if (pstr != NULL)
        printf("-p was specified with the value \"%s\"\n", pstr);
    if (optind < argc)
        printf("First non-option argument is \"%s\" at argv[%d]\n",
               argv[optind], optind);

    exit(EXIT_SUCCESS);
}

命令示例:

./program_name -p hello

输出:

opt = 112 (p); optind = 3
-p was specified with the value "hello"
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn