Linux中getopt函式、optind等變數使用詳解
getopt函式、optind等變數使用詳解
最近在學習《Unix網路程式設計》vol2時,發現書中例子經常使用一個命令列解析getopt函式,因為函式宣告比較特別,根據自己摸索,遂總結出使用方法。
1. getopt函式的宣告
該函式是由Unix標準庫提供的函式,檢視命令man 3 getopt
#include <unistd.h>
int getopt(int argc, char * const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
getopt函式的引數:
- 引數argc和argv:通常是從main的引數直接傳遞而來,argc是引數的數量,argv是一個常量字串陣列的地址。
- 引數optstring:一個包含正確選項字元的字串,如果一個字元後面有冒號,那麼這個選項在傳遞引數時就需要跟著一個引數。
外部變數:
- char *optarg:如果有引數,則包含當前選項引數字串
- int optind:argv的當前索引值。當getopt函式在while迴圈中使用時,剩下的字串為運算元,下標從optind到argc-1。
- int opterr:這個變數非零時,getopt()函式為“無效選項”和“缺少引數選項,並輸出其錯誤資訊。
- int optopt:當發現無效選項字元之時,getopt()函式或返回 \’ ? \’ 字元,或返回字元 \’ : \’ ,並且optopt包含了所發現的無效選項字元。
根據下面的程式理解這四個引數:
2. getopt函式的使用
在man 3 getopt
給出了該函式的例子
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int flags = 0, opt;
int nsecs = 0, tfnd = 0;
while((opt = getopt(argc, argv, "nt:")) != -1) {
switch (opt) {
case 'n':
flags = 1;
break;
case 't':
nsecs = atoi(optarg);
tfnd = 1;
break;
default:
printf("optopt = %c\n", (char)optopt);
printf("opterr = %d\n", opterr);
fprintf(stderr, "usage: %s [-t nsecs] [-n] name\n", argv[0]);
exit(EXIT_FAILURE);
}
}
printf("flags = %d; tfnd = %d; nsecs = %d; optind = %d\n", flags, tfnd, nsecs, optind);
printf("optind = %d\n", optind);
printf("argc = %d\n", argc);
#if 1
if(optind >= argc) {
fprintf(stderr, "Expected argument after options\n");
exit(1);
}
#endif
printf("name argument = %s\n", argv[optind]);
/* Other code omitted */
return 0;
}
- getopt函式的第三個字串引數 “nt:”:在man page中這樣解釋:-n, with no associated value; and -t val, which expects an associated value。中文意思為:-n 不用一個關聯值;-t 需要有一個關聯的value引數。
執行結果:
➜ test ./a.out -a name //首先 -a 是一個非法的選項
./a.out: invalid option -- 'a' //輸出錯誤資訊,因為非法選項
optind = 2 //此時argv[optind]是我們的運算元,也就是我們傳遞給主函式的引數
optopt = a //當發現無效項字元時,optopt會包含該字元,正如我們傳遞的‘a’這個無效項。
opterr = 1 //opterr變數非零,getopt()函式為“無效選項”和“缺少引數選項,並輸出其錯誤資訊。
usage: ./a.out [-t nsecs] [-n] name
再次執行:
➜ test ./a.out -t //根據getopt函式的第三個引數,因為‘t’字元後有‘:’冒號,因此在‘-t’選項後需要跟隨一個引數。因此此次執行的錯誤為“缺少引數”,如下提示:
./a.out: option requires an argument -- 't' //輸出了錯誤資訊,因為“缺少引數”
optind = 2 //argv[optind]為空,因為此次執行沒有傳遞引數
optopt = t //當發現無效項字元時,optopt會包含該字元,正如我們傳遞的‘t’缺少引數的選項。
opterr = 1 //opterr變數非零,getopt()函式為“無效選項”和“缺少引數“選項,並輸出其錯誤資訊。
usage: ./a.out [-t nsecs] [-n] name
再次執行:
➜ test ./a.out -t 123 -n //此時,根據字串”-nt:“應該得知,-t 後應加引數,-n不用加
flags = 1; tfnd = 1; nsecs = 123; optind = 4 //在switch語句中將flags=1,tfnd=1,因為optarg變數儲存這當前選項引數的字串,因此此時optarg儲存的是‘-t’引數的引數並用atoi函式轉稱整數,因此nsecs=123。
optind = 4 //argv[optind]為空,因為沒有向主函式傳遞引數
argc = 4 //一共四個字串
Expected argument after options //該程式希望我們至少傳遞一個引數,因此在if語句中退出。
再次執行:
➜ test ./a.out -t 123 -n hello //‘-t’後加引數,‘-n’不用加,向main函式傳遞引數叫hello
flags = 1; tfnd = 1; nsecs = 123; optind = 4
optind = 4 //argv[optind] = ”hello“
argc = 5 //五個字串
name argument = hello //列印引數name argument= hello
其實可以傳遞多個引數(如果需要,因為此函式只列印第一個引數),例如:
➜ test ./a.out -t 123 -n hello world hello C
optind = 3
optind = 4
flags = 1; tfnd = 1; nsecs = 123; optind = 4
optind = 4
argc = 8
name argument = hello
相關文章
- linux系統getopt函式詳解Linux函式
- 命令列引數解析函式getopt_long() 使用詳解命令列函式
- Linux下getopt函式的使用Linux函式
- Linux選項解釋-getopt和getopt_long函式Linux函式
- Linux下getopt()函式的簡單使用Linux函式
- linux之getopt 函式(轉)Linux函式
- linux的命令列解析引數之getopt_long函式使用Linux命令列函式
- 命令列引數選項處理:getopt()及getopt_long()函式使用命令列函式
- linux下getopt函式的用法Linux函式
- linux中fork()函式詳解Linux函式
- getopt_long函式基本用法-linux函式Linux
- 函式引數詳解函式
- 13.1 函式中的變數函式變數
- ConcurrentHashMap(一):常量,成員變數,靜態程式碼塊,內部類,spread函式,tabAt函式等詳解HashMap變數函式BAT
- 1.linux的命令列解析引數之getopt_long函式Linux命令列函式
- C/C++—— 分析命令列引數的getopt()函式使用介紹C++命令列函式
- 一個使用getopt()函式獲取命令列引數的例子(轉)函式命令列
- 例項詳解 Linux 中的 fork() 函式Linux函式
- OpenCV中的findContours函式引數詳解OpenCV函式
- javascript變數物件函式呼叫棧作用域閉包等細解!JavaScript變數物件函式
- 詳解Linux bash變數Linux變數
- 【多程式】Linux中fork()函式詳解|多程式Linux函式
- TypeScript中的函式詳解TypeScript函式
- Oracle中pivot函式詳解Oracle函式
- linux signal函式詳解Linux函式
- linux時間函式詳解Linux函式
- Qt5.9中QObject::connect()函式用法(函式使用的前提條件和引數詳解)QTObject函式
- linux 中getopt和getopt_long 用法解析Linux
- setdefaultencoding函式使用詳解Encoding函式
- linux 條件變數詳解Linux變數
- 《前端實戰總結》之變數提升,函式宣告提升及變數作用域詳解前端變數函式
- exe等函式使用函式
- 詳解MySQL中的SQRT函式的使用方法MySql函式
- MySQL中count(*)函式原理詳解MySql函式
- Python中的函式詳解Python函式
- Python中Numpy函式詳解Python函式
- linux的umask函式詳解(轉)Linux函式
- Linux 中 RPM 命令引數使用詳解Linux