1. 程式人生 > >Linux下 頭文件<getopt.h> 及其函數的應用

Linux下 頭文件<getopt.h> 及其函數的應用

har inux 開始 內部 tin 空格 %d .cn 如果

本文內容摘抄自:https://www.cnblogs.com/qingergege/p/5914218.html

函數一:

int getopt(int argc, char* argv[], const char* optstring);

參數1、2為 main函數的輸入參數,參數3 為選項字符串,函數返回值為選項字符。

<getopt.h 文件內部的參數:

1、 extern char* optarg ; 用於保存選項。

2、 extern int optind, 用來記錄下一個檢索位置。

3、 extern int opterr, 是否將錯誤的信息輸出到stderr,為0時表示不輸出。

4、 extern int optopt, 表示不在選項字符串optstring中的選項。

先來看一條指令: gcc helloworld.c -o helloworld.out; 這條指令中的-o就是命令行的選項,而後面的helloworld.out 就是選項-o選項所攜帶的參數。 有些選項是不帶參數的,而這樣不帶參數的選項可以寫在一起, 比如說有兩個選項 -c和-d,這兩個選項都不帶參數,那麽他們是可以寫在一起的,即:-cd 。

關於選項字符串: 比如 “a:b:cd::e”,這就是一個選項字符串。對應到命令行就是 -a, -b, -c, -d, -e 。 冒號表示參數,一個冒號就表示這個選項後面必須帶有參數。這個參數可以和選項連在一起,也可以用空格隔開,比如:-a123 和 -a 123 ,都表似乎123為-a的參數。兩個冒號就表示這個選項的參數是可選的,即可以有參數也可以沒有參數,但要註意有參數時參數與選項之間不能有空格。

一個例子:

/*
 ============================================================================
 Name        : test.c
 Author      : lgh
 ============================================================================
 */

#include <unistd.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
    
int ch; printf("\n\n"); printf("optind:%d, opterr:%d\n",optind,opterr); printf("-----------------------------------------------------------\n"); while((ch = getopt(argc, argv, "ab:c:de::")) != -1) { switch(ch) { case a: printf("a\n\n"); printf("the argument of -a is %s\n\n",optarg); break; case b: printf("b\n\n"); printf("the argument of -b is %s\n\n",optarg); break; case c: printf("c\n\n"); printf("the argument of -c is %s\n\n",optarg); break; case d: printf("d\n\n"); break; case e: printf("e\n\n"); printf("the argument of -e is %s\n\n",optarg); break; case ?: printf("unknown option: %c\n",(char)optopt); break; } printf("下一次起始搜索位置:optind = %d\n",optind); printf("-----------------------------------------------------------\n"); printf("\n\n"); } }

編譯後命令執行 ./test -b "hello world"

輸出結果為:

optind:1, opterr:1
-----------------------------------------------------------
b

the argument of -b is hello world

下一次起始搜索位置:optind = 3
-----------------------------------------------------------

可以看到optind 和 opterr的初始值都為1 ,opterr非零表示如果發生錯誤,會將錯誤輸出到stderr上。

int main(int argc, char* argv[]); argc表示參數的個數,argv[]表示每個參數字符串。 對於./test -b "hello world" 命令,argc就為3,argv[]分別表示./test -b "hello world" , 實際上真正的參數從 -b 開始,也就是argv[1] ,所以optind的初始值就是1。

當執行getopt()函數時,會依次掃描每一個命令行參數(下標1開始),第一個-b是一個選項,而且這個選項在選項字符串optstring中有,b後面有冒號表示b後面必須帶有參數, “hello world”就是它的參數。所以這個命令行是符合要求的。至於執行後optind為什麽是3,這是因為optind是下一次getopt()函數要從argv[3]開始搜索。當然,這個例子argv[3]已經沒有了,此時getopt()函數會返回-1,結束while循環。

再次輸入一行命令: ./test -b "hello world" -c1234

輸出結果為:

optind:1, opterr:1
-----------------------------------------------------------
b

the argument of -b is hello world

下一次起始搜索位置:optind = 3
-----------------------------------------------------------


c

the argument of -c is 1234

下一次起始搜索位置:optind = 4
-----------------------------------------------------------

對於這個過程,最開始optind=1 ,找到選項-b 和他的參數“hello world” ,之後搜索起始位置跳至argv[3] 找到 -c和他的參數1234(選項和參數是連在一起的),由於-c1234是寫在一起的,所以他倆一起占用argv[3] ,之後搜索起始位置跳至 argv[4] ,而argv[4]為空,這樣getopt()函數就會返回-1,循環結束。

再次輸入命令: ./test -z 123

輸出結果為:

optind:1, opterr:1
-----------------------------------------------------------
./test: invalid option -- z
unknown option: z
下一次起始搜索位置:optind = 2
-----------------------------------------------------------

其中./test: invalid option -- ‘z‘ 就是輸出到stderr的錯誤輸出 ,如果把opterr設置為0那麽就不會有這條輸出。

再次輸入命令: ./test -zheng

輸出結果為:

optind:1, opterr:1
-----------------------------------------------------------
./test: invalid option -- z
unknown option: z
下一次起始搜索位置:optind = 1
-----------------------------------------------------------


./test: invalid option -- h
unknown option: h
下一次起始搜索位置:optind = 1
-----------------------------------------------------------


e

the argument of -e is ng

下一次起始搜索位置:optind = 2
-----------------------------------------------------------

由於不帶參數的選項可以寫在一起,所以當getopt()函數找到-z的時候,發現在optstring中沒有,這時候他就認為h也是一個選項,也就是-h 和 -z寫在一起了,依次類推,直到找到-e,發現optstring中有。

Linux下 頭文件<getopt.h> 及其函數的應用