作者:gnuhpc
出處:http://www.cnblogs.com/gnuhpc/
1.getopt
#include <unistd.h>
extern char *optarg;
extern int optind;
extern int optopt;
extern int opterr;
extern int optreset;
int getopt(int argc, char * const *argv, const char *optstring);
getopt()每調用一次返回一個選項。 argc 和 argv 很顯然就是 main 函數的兩個參數。
字串 optstring 可以包含下列元素:單個字元,字元後面接一個冒號說明後面跟隨一個選項參數,字元後面接兩個冒號說明後面跟隨一個可有可無的選項參數。例如,一個選項字元 "x" 表示選項 "-x" ,選項字元 "x:" 表示選項和其參數 "-x argument",選項字元 "x::" 表示選項 x 的參數是可選的(“::” 是 GNU 增加的,不一定在所有的UNIX 系統下都可以使用)。
getopt()的返回後,如果有選項參數的話 optarg 指向選項參數,並且變數 optind 包含下一個 argv 參數作為對 getopt() 下一次調用的索引。變數 optopt 儲存最後一個由 getopt() 返回的已知的選項。
當參數列已經到結尾時getopt()函數返回-1,當遇到一個未知的選項時 getopt 返回'?'。參數列中選項的解釋可能會被'--'取消,由於它引起 getopt()給參數處理髮送結束訊號並返回-1。
很多時候,我們不希望輸出任何錯誤資訊,或更希望輸出自己定義的錯誤資訊。可以採用以下兩種方法來更改getopt()函數的出錯資訊輸出行為:
在調用getopt()之前,將opterr設定為0,這樣就可以在getopt()函數發現錯誤的時候強制它不輸出任何訊息。
如果optstring參數的第一個字元是冒號,那麼getopt()函數就會保持沉默,並根據錯誤情況返回不同字元,如下:
“無效選項” ―― getopt()返回'?',並且optopt包含了無效選項字元(這是正常的行為)。
“缺少選項參數” ―― getopt()返回':',如果optstring的第一個字元不是冒號,那麼getopt()返回'?',這會使得這種情況不能與無效選項的情況區分開。
/* getopt.c */
#include <unistd.h>
#include <stdio.h>
int main(int argc, char * argv[])
{
int aflag=0, bflag=0, cflag=0;
int ch;
while ((ch = getopt(argc, argv, "ab:c")) != -1)
{
printf("optind: %d/n", optind);
switch (ch) {
case 'a':
printf("HAVE option: -a/n");
aflag = 1;
break;
case 'b':
printf("HAVE option: -b/n");
bflag = 1;
printf("The argument of -b is %s/n", optarg);
break;
case 'c':
printf("HAVE option: -c");
cflag = 1;
break;
case '?':
printf("Unknown option: %c/n",(char)optopt);
break;
}
}
}
2.getopt_long
int getopt_long(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
其中我們使用了一個結構體struct options的數組,struct options longopt[].
struct options的定義如下:
struct option{
const char *name;
int has_arg;
int *flag;
int val;
};
對結構中的各元素解釋如下:
const char *name
這是選項名,前面沒有虛線。譬如"help"、"verbose"之類。
int has_arg
描述了選項是否有選項參數。如果有,是哪種類型的參數,此時,它的值一定是下表中的一個。
符號常量 數值 含義
no_argument 0 選項沒有參數
required_argument 1 選項需要參數
optional_argument 2 選項參數可選
int *flag
如果這個指標為NULL,那麼 getopt_long()返回該結構val欄位中的數值。如果該指標不為NULL,getopt_long()會使得它所指向的變數中填入val欄位中的數值,並且getopt_long()返回0。如果flag不是NULL,但未發現長選項,那麼它所指向的變數的數值不變。
int val
這個值是發現了長選項時的傳回值,或者flag不是NULL時載入*flag中的值。典型情況下,若flag不是NULL,那麼val是個真/假值,譬如 1或0;另一方面,如果flag是NULL,那麼 val通常是字元常量,若長選項與短選項一致,那麼該字元常量應該與optstring中出現的這個選項的參數相同。
每個長選項在長選項表中都有一個單獨條目,該條目裡需要填入正確的數值。數組中最後的元素的值應該全是0。數組不需要排序,getopt_long()會進行線性搜尋。但是,根據長名字來排序會使程式員讀起來更容易。
#include <stdio.h>
#include <getopt.h>
int do_name, do_gf_name;
char *l_opt_arg;
static const char *shortopts = "l:ng";
struct option longopts[] = {
{"name", no_argument, NULL, 'n'},
{"gf_name", no_argument, NULL, 'g'},
{"love", required_argument, NULL, 'l'},
{0, 0, 0, 0},
};
int main (int argc, char *argv[])
{
int c;
while ((c = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
{
switch (c)
{
case 'n':
printf ("My name is LYR./n");
break;
case 'g':
printf ("Her name is BX./n");
break;
case 'l':
l_opt_arg = optarg;
printf ("Our love is %s!/n", l_opt_arg);
break;
}
}
return 0;
}
具體案例:
/* getopt_demo - demonstrate getopt() usage * * This application shows you one way of using getopt() to * process your command-line options and store them in a * global structure for easy access. */#include <stdio.h>#include <stdlib.h>#include <unistd.h>/* doc2html supports the following command-line arguments: * * -I - don't produce a keyword index * -l lang - produce output in the specified language, lang * -o outfile - write output to outfile instead of stdout * -v - be verbose; more -v means more diagnostics * additional file names are used as input files * * The optString global tells getopt() which options we * support, and which options have arguments. */struct globalArgs_t { int noIndex; /* -I option */ char *langCode; /* -l option */ const char *outFileName; /* -o option */ FILE *outFile; int verbosity; /* -v option */ char **inputFiles; /* input files */ int numInputFiles; /* # of input files */} globalArgs;static const char *optString = "Il:o:vh?";/* Display program usage, and exit. */void display_usage( void ){ puts( "doc2html - convert documents to HTML" ); /* ... */ exit( EXIT_FAILURE );}/* Convert the input files to HTML, governed by globalArgs. */void convert_document( void ){ printf("InputFiles:%d/n",globalArgs.numInputFiles); /* ... */}int main( int argc, char *argv[] ){ int opt = 0; /* Initialize globalArgs before we get to work. */ globalArgs.noIndex = 0; /* false */ globalArgs.langCode = NULL; globalArgs.outFileName = NULL; globalArgs.outFile = NULL; globalArgs.verbosity = 0; globalArgs.inputFiles = NULL; globalArgs.numInputFiles = 0; /* Process the arguments with getopt(), then * populate globalArgs. */ opt = getopt( argc, argv, optString ); while( opt != -1 ) { switch( opt ) { case 'I': globalArgs.noIndex = 1; /* true */ break; case 'l': globalArgs.langCode = optarg; break; case 'o': /* This generates an "assignment from * incompatible pointer type" warning that * you can safely ignore. */ globalArgs.outFileName = optarg; break; case 'v': globalArgs.verbosity++; break; case 'h': /* fall-through is intentional */ case '?': display_usage(); break; default: /* You won't actually get here. */ break; } printf("optind=%d/n",optind); opt = getopt( argc, argv, optString ); } globalArgs.inputFiles = argv + optind; globalArgs.numInputFiles = argc - optind; printf("argc=%d/n",argc); printf("optind=%d/n",optind); convert_document(); return EXIT_SUCCESS;}
作者:gnuhpc
出處:http://www.cnblogs.com/gnuhpc/