C語言中getopt()和getopt_long()函式的用法
一、命令列引數的使用
C程式的主函式有兩個引數,其中,第一個引數是整型,可以獲得包括程式名字的引數個數,第二個引數是字元陣列指標或字元指標的指標,可以按順序獲得命令列上各個字串引數。其原形是:
int main(int argc, char *argv[]);
或者是:int main(int argc, char **argv);
比如在命令列輸入:./test hello world
則argc=3,argv[0]="./test",argv[1]="hello",argv[3]="world"
在主函式中可以直接對命令列引數進行處理,但當命令列引數個數較多時,如果按照順序一個一個定義引數含義很容易造成混亂,而且如果程式只按順序處理引數的話,一些“可選引數”的功能將很難實現。在Linux中,可以使用getopt()、getopt_long()、getopt_long_only()等函式來對複雜的命令列引數進行處理。
二、getopt()函式
原型:#include <unistd.h>
extern char *optarg;
extern int optind, opterr, optopt;
int getopt(int argc, char * const argv[], const char *optstring);
描述:
1、getopt函式的前兩個引數,就是main函式的argc和argv,這兩者直接傳入即可,要考慮的就只剩下第三個引數。
2、optstring的格式舉例說明比較方便,例如:
char *optstring = "abcd:";
上面這個optstring在傳入之後,getopt函式將依次檢查命令列是否指定了 -a, -b, -c及 -d(這需要多次呼叫getopt函式,直到其返回-1),當檢查到上面某一個引數被指定時,函式會返回被指定的引數名稱(即該字母)最後一個引數d後面帶有冒號,: 表示引數d是可以指定值的,如 -d 100 或 -d user。字元後帶兩個':'表示該選項帶可選引數(引數可有可無)。
3、optind表示的是下一個將被處理到的引數在argv中的下標值。
4、如果指定opterr = 0的話,在getopt、getopt_long、getopt_long_only遇到錯誤將不會輸出錯誤資訊到標準輸出流。
例一:
#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) { printf("optind: %d\n", optind); switch (ch) { case 'a': printf("HAVE option: -a\n\n"); break; case 'b': printf("HAVE option: -b\n"); printf("The argument of -b is %s\n\n", optarg); break; case 'c': printf("HAVE option: -c\n"); printf("The argument of -c is %s\n\n", optarg); break; case 'd': printf("HAVE option: -d\n"); break; case 'e': printf("HAVE option: -e\n"); printf("The argument of -e is %s\n\n", optarg); break; case '?': printf("Unknown option: %c\n",(char)optopt); break; } } }
例二:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
int opt;
char *optstring = "a:b:c:d";
while ((opt = getopt(argc, argv, optstring)) != -1)
{
printf("opt = %c\n", opt);
printf("optarg = %s\n", optarg);
printf("optind = %d\n", optind);
printf("argv[optind - 1] = %s\n\n", argv[optind - 1]);
}
return 0;
}
輸出結果;[email protected]:~/Desktop/getopt$ ./test_getopt -a 100 -b 200 -c admin -d
opt = a
optarg = 100
optind = 3
argv[optind - 1] = 100
opt = b
optarg = 200
optind = 5
argv[optind - 1] = 200
opt = c
optarg = admin
optind = 7
argv[optind - 1] = admin
opt = d
optarg = (null)
optind = 8
argv[optind - 1] = -d
三、getopt_long()函式
getopt_long函式包含了getopt函式的功能,並且還可以指定“長引數”(或者說長選項),與getopt函式對比,getopt_long比其多了兩個引數。
原型:
#define _GNU_SOURCE
#include <getopt.h>
extern char *optarg;
extern int optind, opterr, optopt;
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex);
int getopt_long_only(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex);
描述:
1、注意相比getopt,使用getopt_long需要加標頭檔案<getopt.h>;
2、getopt_long除了會接受長選項,其他概念和getopt是一樣的;
3、如果使用getopt_long想只接受短選項,設定longopts為NULL即可;如果只想接受長選項,相應地設定optstring為NULL即可;
4、長選項名是可以使用縮寫方式,比如:選項有--file\--create,那麼輸入--c/--cr/--cre等均會被正確識別為create選項;
5、對於帶引數的長選項格式是:--arg=param或--arg param;
6、longopts是指向struct option陣列的第一個元素的指標,struct option定義在<getopt.h>中;
7、longindex如果非NULL,則是返回識別到struct option陣列中元素的位置指標;
8、當所給的引數存在問題時,函式的返回值是'?'
struct option的說明:
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
name: 長選項名
has_arg: 是否帶引數或可選引數,這個值在getopt.h中有巨集定義,如下:
# define no_argument 0 表明這個長引數不帶引數(即不帶數值,如:--name)
# define required_argument 1 表明這個長引數必須帶引數(即必須帶數值,如:--name Bob)
# define optional_argument 2 表明這個長引數後面帶的引數是可選的,(即--name和--name Bob均可)
flag: 確定函式返回值的情況,如果flag==NULL,則識別選項後返回val(常用的如:設定val為長命令的短命令字元);否則,識別後getopt_long返回0,flag指向一個設定到val的變數;
val: 設定為返回值,或者是flag指向的變數;這裡要注意不要寫-1到val,否則其作用是getopt_long返回-1,然後停止解析選項;
[注意] longopts的最後一個元素必須是全0填充,否則會報段錯誤
例子:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
int
main(int argc, char **argv)
{
int opt;
int digit_optind = 0;
int option_index = 0;
char *optstring = "a:b:c:d";
static struct option long_options[] = {
{"reqarg", required_argument, NULL, 'r'},
{"noarg", no_argument, NULL, 'n'},
{"optarg", optional_argument, NULL, 'o'},
{0, 0, 0, 0}
};
while ( (opt = getopt_long(argc, argv, optstring, long_options, &option_index)) != -1)
{
printf("opt = %c\n", opt);
printf("optarg = %s\n", optarg);
printf("optind = %d\n", optind);
printf("argv[optind - 1] = %s\n", argv[optind - 1]);
printf("option_index = %d\n", option_index);
}
return 0;
}
輸出結果:
[[email protected] c]$ ./test_getopt -a 100 --reqarg 100 --noarg
opt = a
optarg = 100
optind = 3
argv[optind - 1] = 100
option_index = 0
opt = r
optarg = 100
optind = 5
argv[optind - 1] = 100
option_index = 0
opt = n
optarg = (null)
optind = 6
argv[optind - 1] = --noarg
option_index = 1
最後說明一下,getopt_long_only與getopt_long的區別在於:getopt_long僅僅只能將"--"開始的選項視為長選項,但getopt_long_only將"-"開頭選項也會視為長選項,當長選項列表均不滿足時,且短選項滿足時,"-"才會解析為短選項;
參考文獻:
相關推薦
C語言中getopt()和getopt_long()函式的用法
一、命令列引數的使用 C程式的主函式有兩個引數,其中,第一個引數是整型,可以獲得包括程式名字的引數個數,第二個引數是字元陣列指標或字元指標的指標,可以按順序獲得命令列上各個字串引數。其原形是: int main(int argc, char *argv[]);或者是:in
關於c語言中malloc和remalloc函式的分析
首先申明,這是本人第一次寫部落格,其目的僅僅是為了加強自己對知識點的掌握,為到達在本子上記筆記的效果 進入正題。對於malloc,它的作用就是為了動態分配空間,像c++中的new一樣。這裡就不說他們兩的區別了。malloc函式有這樣幾個特點。 1.分配的空間地址是連續的,
C語言中printf和scanf函式基本的引數型別和輸出形式
printf函式的引數型別和輸出形式 字元 引數型別 輸出形式 d,i int 十進位制數 o int 無符號八進位制數(不含前導0) x,X int 無符號十六進位制數(沒有前
C語言中static修飾的函式和普通函式的區別
用static修飾的函式,本限定在本原始碼檔案中,不能被本原始碼檔案以外的程式碼檔案呼叫。而普通的函式,預設是extern的,也就是說,可以被其它程式碼檔案呼叫該函式。 在函式的返回型別前加上關鍵字static,函式就被定義成為靜態函式。普通 函式的定義和宣告預設情況下是extern的,但靜
C語言中 typeof()函式的用法
前言: typeof關鍵字是C語言中的一個新擴充套件,這個特性在linux核心中應用非常廣泛。 一,說明 typeof的引數可以是兩種形式: 表示式 或 型別 。
C語言中char*和char[]用法區別分析
本文例項分析了C語言中char* 和 char []的區別。分享給大家供大家參考之用。具體分析如下: 一般來說,很多人會覺得這兩個定義效果一樣,其實差別很大。以下是個人的一些看法,有不正確的地方望指正。 本質上來說,char *s定義了一個char型的指標,它只知道所指向的
c語言中fscanf和fprintf
寫的權限 set per efi errno fclose pri form price 很多時候我們需要寫入數據到文件中時都覺得很困擾,因為格式亂七八槽的,可讀性太差了,於是我們就想有沒有什麽函數可以格式化的從文件中輸入和輸出呢,還真有。下面我將講解一下fscanf和fp
C語言中sprintf()函數的用法
用法 href bsp HA 連接 art tail 格式化 類型轉換 sprintf函數的用法1、該函數包含在stdio.h的頭文件中。 2、sprintf和平時我們常用的printf函數的功能很相似。sprintf函數打印到字符串中,而printf函數打印輸出到屏幕
C語言中typedef和sizeof的註意事項
isp sizeof spa 註意 list數據 對象 audio 應該 user typedef的作用是給一個數據類型起一個別名。 typedef struct LIST { int data; }SeqList; SeqList 就相當於struct LIS
c語言中external,static關鍵字用法
static用法: 在C中,static主要定義全域性靜態變數、定義區域性靜態變數、定義靜態函式。 1、定義全域性靜態變數:在全域性變數前面加上關鍵字static,該全域性變數變成了全域性靜態變數。全域性靜態變數有以下特點。 a.在全域性區分配記憶體。 b.如果沒有初始化,其預設值為
C語言中 malloc 和 free
from:http://blog.sina.com.cn/s/blog_af1a77fa0102xceb.html 一、malloc()和free()的基本概念以及基本用法: 1、函式原型及說明: void *malloc(long NumBytes):該函式分配了NumBytes個位元
c語言中strchr()字串處理函式
strchr()這個函式並不像strcpy(),strcat(),strcmp(),strupr(),strlwr(),strlen()這幾個字串處理函式那麼直觀,所以需要通過一個程式碼來理解一下: 程式碼來自c語言開發入門及專案實戰一書: #include<stdi
c語言中static和auto的區別
1、static變數存放在靜態儲存區,在程式整個執行期間都不釋放;而auto變數存放在動態儲存區,隨著生命週期的結束而立即釋放。 2、static變數只賦值一次,以後就不用賦值;而auto變數在函式每呼叫一次都要賦初值
關於C語言中“x++”和“++x”的問題
關於一個變數在不同環境下自增自減的問題。 #include<stdio.h> int main() { int x = 8; int y = 0; y = (++x) + (x++) + (++x); printf("%d\n",y);
C語言中“指標”和“指標變數”的區別是什麼
比較嚴格的說法是這樣的:系統為每一個記憶體單元分配一個地址值,C/C++把這個地址值稱為“指標”。如有int i=5;,存放變數i的記憶體單元的編號(地址)&i被稱為指標。“指標變數”則是存放前述“地址值”的變數,也可以表述為,“指標變數”是存放變數所佔記憶體空間“
C語言中i++和++i的區別
C語言中i++和++i的區別 C語言中++i和i++是有區別的!快速理解的話就是用一句話概括: 1、i++是先賦值再運算+1; 2、++i是先運算+1再賦值; i++和++i都是c語言裡的自增,但是它們自增的順序不同。++i表示,i自增1後再參與其它運算,而i++ 則是i參與運算後,i的
C語言中char * 和 char []的區別
問題引入: 在實習過程中發現了一個以前一直預設的錯誤,同樣char *c = "abc"和char c[]="abc",前者改變其內容程式是會崩潰的,而後者完全正確。 程式演示: #include <iostream> usingnamespa
C語言中,如何通過函式來改變一個變數的值
最近看面試題,遇到一些關於通過函式改變一個變數的值得問題,現在終結一下: 先看下面一段程式碼: #include <stdio.h>#include <stdlib.h> void GetMemory(char *p) { p=(char
C語言中const和C++中const關鍵字的區別
# include "iostream" using namespace std; struct Teacher { char name[30]; int age; }; void operatorTeacher(Teacher *pT) {
由淺至深->C語言中union和enum關鍵字的經典問題分析
引言:由淺至深系列的第二篇文章,繼續體悟語言中的一些細節! 文章嚮導 union的自我介紹 union與系統大小端 enum列舉的引入 真正意義上的常量? 正文 一、union的自我介紹 union(聯合/共用體)在語