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