青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

yeqing

C++博客 首頁 新隨筆 聯(lián)系 聚合 管理
  1 Posts :: 14 Stories :: 10 Comments :: 0 Trackbacks

Linux下很多程序甚至那些具有圖形用戶界面(graphical user interface,GUI)的程序,都能接受和處理命令行選項(xiàng)。對于某些程序,這是與其他程序或用戶進(jìn)行交互的主要手段。具有可靠的復(fù)雜命令行參數(shù)處理機(jī)制,會使得您的應(yīng)用程序更好、更有用。不過很多開發(fā)人員都將其寶貴的時(shí)間花在了編寫自己的命令行解析器,卻不使用 getopt(),而后者是一個(gè)專門設(shè)計(jì)來減輕命令行處理負(fù)擔(dān)的庫函數(shù)。

?

1、命令行參數(shù)
命令行程序設(shè)計(jì)的首要任務(wù)是解析命令行參數(shù),GUI派的程序員很少關(guān)心這個(gè)。這里,我們對參數(shù)(argument)采用了一種比較通俗的定義:命令行上除命令名之外的字符串。參數(shù)由多項(xiàng)構(gòu)成,項(xiàng)與項(xiàng)之間用空白符彼此隔開。
參數(shù)進(jìn)一步分為選項(xiàng)和操作數(shù)。選項(xiàng)用于修改程序的默認(rèn)行為或?yàn)槌绦蛱峁┬畔ⅲ容^老的約定是以短劃線開頭。選項(xiàng)后可以跟隨一些參數(shù),稱為選項(xiàng)參數(shù)。剩下的就是操作數(shù)了。
2、POSIX約定
POSIX表示可移植操作系統(tǒng)接口:Portable Operating System Interface,電氣和電子工程師協(xié)會(Institute of Electrical and Electronics Engineers,IEEE)最初開發(fā) POSIX 標(biāo)準(zhǔn),是為了提高 UNIX 環(huán)境下應(yīng)用程序的可移植性。然而,POSIX 并不局限于 UNIX。許多其它的操作系統(tǒng),例如 DEC OpenVMS 和 Microsoft Windows NT,都支持 POSIX 標(biāo)準(zhǔn)。
?

下面是POSIX標(biāo)準(zhǔn)中關(guān)于程序名、參數(shù)的約定:

程序名不宜少于2個(gè)字符且不多于9個(gè)字符;
程序名應(yīng)只包含小寫字母和阿拉伯?dāng)?shù)字;
選項(xiàng)名應(yīng)該是單字符活單數(shù)字,且以短橫‘-‘為前綴;
多個(gè)不需要選項(xiàng)參數(shù)的選項(xiàng),可以合并。(譬如:foo -a -b -c ---->foo -abc)
選項(xiàng)與其參數(shù)之間用空白符隔開;
選項(xiàng)參數(shù)不可選。
若選項(xiàng)參數(shù)有多值,要將其并未一個(gè)字串傳進(jìn)來。譬如:myprog -u "arnold,joe,jane"。這種情況下,需要自己解決這些參數(shù)的分離問題。
選項(xiàng)應(yīng)該在操作數(shù)出現(xiàn)之前出現(xiàn)。
特殊參數(shù)‘--'指明所有參數(shù)都結(jié)束了,其后任何參數(shù)都認(rèn)為是操作數(shù)。
選項(xiàng)如何排列沒有什么關(guān)系,但對互相排斥的選項(xiàng),如果一個(gè)選項(xiàng)的操作結(jié)果覆蓋其他選項(xiàng)的操作結(jié)果時(shí),最后一個(gè)選項(xiàng)起作用;如果選項(xiàng)重復(fù),則順序處理。
允許操作數(shù)的順序影響程序行為,但需要作文檔說明。
讀寫指定文件的程序應(yīng)該將單個(gè)參數(shù)'-'作為有意義的標(biāo)準(zhǔn)輸入或輸出來對待。
當(dāng)然許多標(biāo)準(zhǔn)從恒許未遵守以上約定,主要是歷史兼容問題,因?yàn)闃?biāo)準(zhǔn)出現(xiàn)之前,就已經(jīng)存在N多程序了。

3、GNU長選項(xiàng)
GNU鼓勵(lì)程序員使用--help、--verbose等形式的長選項(xiàng)。這些選項(xiàng)不僅不與POSIX約定沖突,而且容易記憶,另外也提供了在所有GNU工具之間保持一致性的機(jī)會。GNU長選項(xiàng)有自己的約定:

對于已經(jīng)遵循POSIX約定的GNU程序,每個(gè)短選項(xiàng)都有一個(gè)對應(yīng)的長選項(xiàng)。
額外針對GNU的長選項(xiàng)不需要對應(yīng)的短選項(xiàng),僅僅推薦要有。
長選項(xiàng)可以縮寫成保持惟一性的最短的字串。
選項(xiàng)參數(shù)與長選項(xiàng)之間或通過空白字符活通過一個(gè)'='來分隔。
選項(xiàng)參數(shù)是可選的(只對短選項(xiàng)有效)。
長選項(xiàng)允許以一個(gè)短橫線為前綴。

4、基本的命令行處理技術(shù)
C程序通過argc和argv參數(shù)訪問它的命令行參數(shù)。argc是整型數(shù),表示參數(shù)的個(gè)數(shù)(包括命令名)。main()函數(shù)的定義方式有兩種,區(qū)別僅在于argv如何定義:

int main(int argc, char *argv[])
{
?? ……
} int main(int argc, char **argv)
{
?? ……
}?


當(dāng) C 運(yùn)行時(shí)庫的程序啟動代碼調(diào)用您的 main() 時(shí),已經(jīng)對命令行進(jìn)行了處理。argc 參數(shù)包含參數(shù)的計(jì)數(shù)值,而 argv 包含指向這些參數(shù)的指針數(shù)組。argv[0]是程序名。

一個(gè)很簡單的命令行處理技術(shù)的例子是echo程序,它可以將參數(shù)輸出到標(biāo)準(zhǔn)設(shè)備上,用空格符隔開,最后換行。若命令行第一個(gè)參數(shù)為-n,那么就不會換行。

清單1:

#include <stdio.h>

int main(int argc, char **argv)
{
??? int i, nflg;

??? nflg = 0;
??? if(argc > 1 && argv[1][0] == '-' && argv[1][1] == 'n'){
??????? nflg++;
??????? argc--;
??????? argv++;
??? }
??? for(i=1; i<argc; i++){
??????? fputs(argv[ i ], stdout);
??????? if(i < argc-1)
??????????? putchar(' ');
??? }
??? if(nflg == 0)
??????? putchar('\n');

??? return 0;
}
?

上面代碼中,加亮區(qū)域仔細(xì)研究一下,會發(fā)現(xiàn)很有趣。

echo程序中,對于命令行參數(shù)的解析是手動實(shí)現(xiàn)的。很久以前,Unix支持小組為了簡化對于命令行參數(shù)的解析,開發(fā)了getopt()函數(shù),同時(shí)提供了幾個(gè)外部變量,使得編寫遵守POSIX的代碼變得更加容易了。

5、命令行參數(shù)解析函數(shù) —— getopt()
getopt()函數(shù)聲明如下:

#include <unistd.h>

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

extern char *optarg;
extern int optind, opterr, optopt;
?

該函數(shù)的argc和argv參數(shù)通常直接從main()的參數(shù)直接傳遞而來。optstring是選項(xiàng)字母組成的字串。如果該字串里的任一字符后面有冒號,那么這個(gè)選項(xiàng)就要求有選項(xiàng)參數(shù)。

當(dāng)給定getopt()命令參數(shù)的數(shù)量 (argc)、指向這些參數(shù)的數(shù)組 (argv) 和選項(xiàng)字串 (optstring) 后,getopt() 將返回第一個(gè)選項(xiàng),并設(shè)置一些全局變量。使用相同的參數(shù)再次調(diào)用該函數(shù)時(shí),它將返回下一個(gè)選項(xiàng),并設(shè)置相應(yīng)的全局變量。如果不再有可識別的選項(xiàng),將返回 -1,此任務(wù)就完成了。

getopt() 所設(shè)置的全局變量包括:

char *optarg——當(dāng)前選項(xiàng)參數(shù)字串(如果有)。
int optind——argv的當(dāng)前索引值。當(dāng)getopt()在while循環(huán)中使用時(shí),循環(huán)結(jié)束后,剩下的字串視為操作數(shù),在argv[optind]至argv[argc-1]中可以找到。
int opterr——這個(gè)變量非零時(shí),getopt()函數(shù)為“無效選項(xiàng)”和“缺少參數(shù)選項(xiàng),并輸出其錯(cuò)誤信息。

int optopt——當(dāng)發(fā)現(xiàn)無效選項(xiàng)字符之時(shí),getopt()函數(shù)或返回'?'字符,或返回':'字符,并且optopt包含了所發(fā)現(xiàn)的無效選項(xiàng)字符。
下面就用getopt()來寫個(gè)小程序,體驗(yàn)一下命令行解析的快樂。

程序描述:

程序名:opt_parse_demo

選項(xiàng):

-n —— 顯示我的名字。
-g —— 顯示我女朋友的名字。
-l —— 帶參數(shù)的選項(xiàng).
清單2:
#include <stdio.h>
#include <unistd.h>

int main (int argc, char **argv)
{
??? int oc;???????????????????? /*選項(xiàng)字符 */
??? char *b_opt_arg;??????????? /*選項(xiàng)參數(shù)字串 */

??? while((oc = getopt(argc, argv, "ngl:")) != -1)
??? {
??????? switch(oc)
??????? {
??????????? case 'n':
??????????????? printf("My name is Lyong.\n");
??????????????? break;
??????????? case 'g':
??????????????? printf("Her name is Xxiong.\n");
??????????????? break;
??????????? case 'l':
??????????????? b_opt_arg = optarg;
??????????????? printf("Our love is %s\n", optarg);
??????????????? break;
??????? }
??? }
?? return 0;
}
?

運(yùn)行結(jié)果:

$ ./opt_parse_demo -n
My name is Lyong.
$ ./opt_parse_demo -g
Her name is Xxiong.
$ ./opt_parse_demo -l forever
Our love is forever
$ ./opt_parse_demo -ngl forever
My name is Lyong.
Her name is Xxiong.
Our love is forever
?

6、改變getopt()對錯(cuò)誤命令行參數(shù)信息的輸出行為
不正確的調(diào)用程序在所難免,這種錯(cuò)誤要么是命令行選項(xiàng)無效,要么是缺少選項(xiàng)參數(shù)。正常情況下,getopt()會為這兩種情況輸出自己的出錯(cuò)信息,并且返回'?'。為了驗(yàn)證此事,可以修改一下上面的清單2中的代碼。

清單3:

#include <stdio.h>
#include <unistd.h>

int main (int argc, char **argv)
{
??? int oc;???????????????????? /*選項(xiàng)字符 */
??? char *b_opt_arg;??????????? /*選項(xiàng)參數(shù)字串 */

??? while((oc = getopt(argc, argv, "ngl:")) != -1)
??? {
??????? switch(oc)
??????? {
??????????? case 'n':
??????????????? printf("My name is Lyong.\n");
??????????????? break;
???????????? case 'g':
??????????????? printf("Her name is Xxiong.\n");
??????????????? break;
??????????? case 'l':
??????????????? b_opt_arg = optarg;
??????????????? printf("Our love is %s\n", optarg);
??????????????? break;
??????????? case '?':
??????????????? printf("arguments error!\n");
??????????????? break;
??????? }
??? }
??? return 0;
}
?

輸入一個(gè)錯(cuò)誤的命令行,結(jié)果如下:

$ ./opt_parse_demo -l
./opt_parse_demo: option requires an argument -- l
arguments error!
?

很多時(shí)候,我們不希望輸出任何錯(cuò)誤信息,或更希望輸出自己定義的錯(cuò)誤信息。可以采用以下兩種方法來更改getopt()函數(shù)的出錯(cuò)信息輸出行為:


在調(diào)用getopt()之前,將opterr設(shè)置為0,這樣就可以在getopt()函數(shù)發(fā)現(xiàn)錯(cuò)誤的時(shí)候強(qiáng)制它不輸出任何消息。
如果optstring參數(shù)的第一個(gè)字符是冒號,那么getopt()函數(shù)就會保持沉默,并根據(jù)錯(cuò)誤情況返回不同字符,如下:
“無效選項(xiàng)” —— getopt()返回'?',并且optopt包含了無效選項(xiàng)字符(這是正常的行為)。
“缺少選項(xiàng)參數(shù)” —— getopt()返回':',如果optstring的第一個(gè)字符不是冒號,那么getopt()返回'?',這會使得這種情況不能與無效選項(xiàng)的情況區(qū)分開。
多說無益,動手測試一下。

清單4:
#include <stdio.h>
#include <unistd.h>

int main (int argc, char **argv)
{
??? int oc;???????????????????? /*選項(xiàng)字符 */
??? char ec;???????????????????????????? /*無效的選項(xiàng)字符*/
??? char *b_opt_arg;??????????? /*選項(xiàng)參數(shù)字串 */

??? while((oc = getopt(argc, argv, ":ngl:")) != -1)
??? {
??????? switch(oc)
??????? {
??????????? case 'n':
??????????????? printf("My name is Lyong.\n");
??????????????? break;
???????????? case 'g':
??????????????? printf("Her name is Xxiong.\n");
??????????????? break;
??????????? case 'l':
??????????????? b_opt_arg = optarg;
??????????????? printf("Our love is %s\n", optarg);
??????????????? break;
??????????? case '?':
??????????????? ec = (char)optopt;
??????????????? printf("無效的選項(xiàng)字符 \' %c \'!\n", ec);
??????????????? break;
??????????? case ':':
??????????????? printf("缺少選項(xiàng)參數(shù)!\n");
??????????????? break;
??????? }
??? }
??? return 0;
}

測試結(jié)果:

$ ./opt_parse_demo -a
無效的選項(xiàng)字符 ' a '!
$ ./opt_parse_demo -l
缺少選項(xiàng)參數(shù)!

7、GNU提供的getopt()函數(shù)的特點(diǎn)
上面所設(shè)計(jì)的getopt()函數(shù)是UNIX支持小組提供的,其執(zhí)行時(shí)一碰到不以'-'開始的命令行參數(shù)就停止尋找選項(xiàng)。而GNU提供的getopt()函數(shù)與之不同,它會掃描整個(gè)命令行來尋找選項(xiàng)。當(dāng)調(diào)用GNU getopt()函數(shù)并處理命令行參數(shù)的時(shí)候,它重新排列argv中的元素,這樣當(dāng)重排結(jié)束時(shí),所有選項(xiàng)都被移動到前面并且那些繼續(xù)檢查argv[optind]至argv[argc-1]中剩余參數(shù)的代碼仍正常工作,但在任何情況下,碰到特殊參數(shù)'--'就結(jié)束對選項(xiàng)的掃描。

可以輸入一個(gè)亂序的命令行,查看opt_parse_demo的輸出:

$ ./opt_parse_demo -l forever a b c d -g -n
Our love is forever
Her name is Xxiong.
My name is Lyong.
?

GNU getopt()第二個(gè)特點(diǎn)是可以在optstring中使用特殊的首字符改變getopt()的默認(rèn)行為:

optstring[0] = '+',這樣就與UNIX支持小組提供的getopt()很相近了。
optstring[0] = '-',會在optarg中得到命令行中的每個(gè)參數(shù)。
以上兩種情況下,':'可以作為第二個(gè)字符使用。
GNU getopt()第三個(gè)特點(diǎn)是optstring中的選項(xiàng)字符后面接兩個(gè)冒號,就允許該選項(xiàng)有可選的選項(xiàng)參數(shù)。在選項(xiàng)參數(shù)不存在的情況下,GNU getopt()返回選項(xiàng)字符并將optarg設(shè)置為NULL。

8、GNU長選項(xiàng)命令行解析
20 世紀(jì) 90 年代,UNIX 應(yīng)用程序開始支持長選項(xiàng),即一對短橫線、一個(gè)描述性選項(xiàng)名稱,還可以包含一個(gè)使用等號連接到選項(xiàng)的參數(shù)。

GNU提供了getopt-long()和getopt-long-only()函數(shù)支持長選項(xiàng)的命令行解析,其中,后者的長選項(xiàng)字串是以一個(gè)短橫線開始的,而非一對短橫線。


getopt_long() 是同時(shí)支持長選項(xiàng)和短選項(xiàng)的 getopt() 版本。下面是它們的聲明:

#include <getopt.h>

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);

?

getopt_long()的前三個(gè)參數(shù)與上面的getopt()相同,第4個(gè)參數(shù)是指向option結(jié)構(gòu)的數(shù)組,option結(jié)構(gòu)被稱為“長選項(xiàng)表”。longindex參數(shù)如果沒有設(shè)置為NULL,那么它就指向一個(gè)變量,這個(gè)變量會被賦值為尋找到的長選項(xiàng)在longopts中的索引值,這可以用于錯(cuò)誤診斷。

option結(jié)構(gòu)在getopt.h中的聲明如下:

struct option{
??? const char *name;
??? int has_arg;
??? int *flag;
??? int val;
};
?

對結(jié)構(gòu)中的各元素解釋如下:

const char *name
這是選項(xiàng)名,前面沒有短橫線。譬如"help"、"verbose"之類。

int has_arg
描述了選項(xiàng)是否有選項(xiàng)參數(shù)。如果有,是哪種類型的參數(shù),此時(shí),它的值一定是下表中的一個(gè)。

符號常量? 數(shù)值? 含義?
no_argument? 0 選項(xiàng)沒有參數(shù)?
required_argument 1 選項(xiàng)需要參數(shù)
?
optional_argument 2 選項(xiàng)參數(shù)可選?

int *flag
如果這個(gè)指針為NULL,那么getopt_long()返回該結(jié)構(gòu)val字段中的數(shù)值。如果該指針不為NULL,getopt_long()會使得它所指向的變量中填入val字段中的數(shù)值,并且getopt_long()返回0。如果flag不是NULL,但未發(fā)現(xiàn)長選項(xiàng),那么它所指向的變量的數(shù)值不變。

int val
這個(gè)值是發(fā)現(xiàn)了長選項(xiàng)時(shí)的返回值,或者flag不是NULL時(shí)載入*flag中的值。典型情況下,若flag不是NULL,那么val是個(gè)真/假值,譬如1或0;另一方面,如果flag是NULL,那么val通常是字符常量,若長選項(xiàng)與短選項(xiàng)一致,那么該字符常量應(yīng)該與optstring中出現(xiàn)的這個(gè)選項(xiàng)的參數(shù)相同。

每個(gè)長選項(xiàng)在長選項(xiàng)表中都有一個(gè)單獨(dú)條目,該條目里需要填入正確的數(shù)值。數(shù)組中最后的元素的值應(yīng)該全是0。數(shù)組不需要排序,getopt_long()會進(jìn)行線性搜索。但是,根據(jù)長名字來排序會使程序員讀起來更容易。

以上所說的flag和val的用法看上去有點(diǎn)混亂,但它們很有實(shí)用價(jià)值,因此有必要搞透徹了。

大部分時(shí)候,程序員會根據(jù)getopt_long()發(fā)現(xiàn)的選項(xiàng),在選項(xiàng)處理過程中要設(shè)置一些標(biāo)記變量,譬如在使用getopt()時(shí),經(jīng)常做出如下的程序格式:

int do_name, do_gf_name, do_love; /*標(biāo)記變量*/
char *b_opt_arg;

while((c = getopt(argc, argv, ":ngl:")) != -1)
{
??? switch (c){
??? case 'n':
??????? do_name = 1;
??? case 'g':
??????? do_gf_name = 1;
??????? break;
??????? break;
??? case 'l':
??????? b_opt_arg = optarg;
??? ……
??? }
}
?

當(dāng)flag不為NULL時(shí),getopt_long*()會為你設(shè)置標(biāo)記變量。也就是說上面的代碼中,關(guān)于選項(xiàng)'n'、'l'的處理,只是設(shè)置一些標(biāo)記,如果flag不為NULL,時(shí),getopt_long()可以自動為各選項(xiàng)所對應(yīng)的標(biāo)記變量設(shè)置標(biāo)記,這樣就能夠?qū)⑸厦娴膕witch語句中的兩種種情況減少到了一種。下面給出一個(gè)長選項(xiàng)表以及相應(yīng)處理代碼的例子。

清單5:

#include <stdio.h>
#include <getopt.h>

int do_name, do_gf_name;
char *l_opt_arg;

struct option longopts[] = {
??? { "name",??????? no_argument,??????????? &do_name,??????? 1??? },
??? { "gf_name",??? no_argument,??????????? &do_gf_name,??? 1??? },
??? { "love",??????? required_argument,??? NULL,??????????????? 'l'??? },
??? {???? 0,??? 0,??? 0,??? 0},
};

int main(int argc, char *argv[])
{
??? int c;
???
??? while((c = getopt_long(argc, argv, ":l:", longopts, NULL)) != -1){
??????? switch (c){
??????? case 'l':
??????????? l_opt_arg = optarg;
??????????? printf("Our love is %s!\n", l_opt_arg);
??????????? break;
??????? case 0:
??????????? printf("getopt_long()設(shè)置變量 : do_name = %d\n", do_name);
??????????? printf("getopt_long()設(shè)置變量 : do_gf_name = %d\n", do_gf_name);
??????????? break;
??????? }
??? }
??? return 0;
}
?

在進(jìn)行測試之前,再來回顧一下有關(guān)option結(jié)構(gòu)中的指針flag的說明吧。

如果這個(gè)指針為NULL,那么getopt_long()返回該結(jié)構(gòu)val字段中的數(shù)值。如果該指針不為NULL,getopt_long()會使得它所指向的變量中填入val字段中的數(shù)值,并且getopt_long()返回0。如果flag不是NULL,但未發(fā)現(xiàn)長選項(xiàng),那么它所指向的變量的數(shù)值不變。

下面測試一下:

$ ./long_opt_demo --name
getopt_long()設(shè)置變量 : do_name = 1
getopt_long()設(shè)置變量 : do_gf_name = 0

$ ./long_opt_demo --gf_name
getopt_long()設(shè)置變量 : do_name = 0
getopt_long()設(shè)置變量 : do_gf_name = 1

$ ./long_opt_demo --love forever
Our love is forever!

$ ./long_opt_demo -l forever
Our love is forever!

?

測試過后,應(yīng)該有所感觸了。關(guān)于flag和val的討論到此為止。下面總結(jié)一下get_long()的各種返回值的含義:

返回值???
?含 義
?
0?????
?getopt_long()設(shè)置一個(gè)標(biāo)志,它的值與option結(jié)構(gòu)中的val字段的值一樣
?
1
?每碰到一個(gè)命令行參數(shù),optarg都會記錄它
?
'?'
?無效選項(xiàng)
?
':'
?缺少選項(xiàng)參數(shù)
?
'x'
?選項(xiàng)字符'x'
?
-1
?選項(xiàng)解析結(jié)束
?

從實(shí)用的角度來說,我們更期望每個(gè)長選項(xiàng)都對應(yīng)一個(gè)短選項(xiàng),這種情況下,在option結(jié)構(gòu)中,只要將flag設(shè)置為NULL,并將val設(shè)置為長選項(xiàng)所對應(yīng)的短選項(xiàng)字符即可。譬如上面清單5中的程序,我們修改如下。

清單6:
#include <stdio.h>
#include <getopt.h>

int do_name, do_gf_name;
char *l_opt_arg;

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, ":l:", 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;
}

測試結(jié)果如下:


$ ./long_opt_demo --name --gf_name --love forever
My name is LYR.
Her name is BX.
Our love is forever!

$ ./long_opt_demo -ng -l forever
My name is LYR.
Her name is BX.
Our love is forever!
?

9、在LINUX之外的系統(tǒng)平臺上使用GNU getopt()或getopt_long()
只要從GNU程序或GNU C Library(GLIBC)的CVS檔案文件中copy源文件即可(
http://sourceware.org/glibc/ )。所需源文件是getopt.h、getopt.c和getoptl.c,將這些文件包含在你的項(xiàng)目中。另外,你的項(xiàng)目中最好也將COPYING.LIB文件包含進(jìn)去,因?yàn)镚NU LGPL(GNU 程序庫公共許可證)的內(nèi)容全部包括在命名為COPYING.LIB 的文件中。沒事時(shí),可以閱讀一下自由軟件的許可協(xié)議,感受一下雷鋒精神。

注意,在包含所需文件之后,在調(diào)用getopt_long()系列函數(shù)的源代碼中,應(yīng)該使用#include "getopt.h",而不是#include <getopt.h>,前者會首先在當(dāng)前目錄中尋找getopt.h。

使用Windows平臺的兄弟可以試用一下,很希望能在這里反饋一下你的使用情況,謝謝。


10、結(jié)論
程序需要能夠快速處理各個(gè)選項(xiàng)和參數(shù),且要求不會浪費(fèi)開發(fā)人員的太多時(shí)間。在這一點(diǎn)上,無論是GUI(圖形用戶交互)程序還是CUI(命令行交互)程序,都是其首要任務(wù),其區(qū)別僅在于實(shí)現(xiàn)方式的不同。GUI通過菜單、對話框之類的圖形控件來完成交互,而CUI使用了純文本的交互方式。各有利弊吧。在程序開發(fā)中,許多測試程序用CUI來完成是首選方案。

getopt() 函數(shù)是一個(gè)標(biāo)準(zhǔn)庫調(diào)用,可允許您使用直接的 while/switch 語句方便地逐個(gè)處理命令行參數(shù)和檢測選項(xiàng)(帶或不帶附加的參數(shù))。與其類似的 getopt_long() 允許在幾乎不進(jìn)行額外工作的情況下處理更具描述性的長選項(xiàng),這非常受開發(fā)人員的歡迎。

既然已經(jīng)知道了如何方便地處理命令行選項(xiàng),現(xiàn)在就可以集中精力改進(jìn)您的程序的命令行,可以添加長選項(xiàng)支持,或添加之前由于不想向程序添加額外的命令行選項(xiàng)處理而擱置的任何其他選項(xiàng)。但不要忘記在某處記錄您所有的選項(xiàng)和參數(shù),并提供某種類型的內(nèi)置幫助函數(shù)來為健忘的用戶提供幫助。

posted on 2006-11-29 09:29 夜沁 閱讀(472) 評論(0)  編輯 收藏 引用 所屬分類: linux

只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品另类一区| 午夜久久电影网| 久久久久综合一区二区三区| 国产日韩1区| 久久亚洲精品视频| 91久久综合亚洲鲁鲁五月天| 美女日韩在线中文字幕| 欧美在线三区| 亚洲国产精品va在线观看黑人 | 国产精品国产三级国产aⅴ9色| 一区福利视频| 欧美激情按摩| 亚洲国产美女| 一本久道久久综合狠狠爱| 宅男精品导航| 欧美中在线观看| 欧美成人国产va精品日本一级| 欧美aa在线视频| 国产精品黄页免费高清在线观看| 国产精品一区二区三区四区| 狠狠色综合日日| 日韩一二在线观看| 欧美一区二区三区视频免费播放 | 久久久久国产精品人| 免费在线看一区| 这里只有精品在线播放| 久久国产精品99国产精| 久久久久久久精| 国产精品swag| 91久久精品国产91性色tv| 欧美一区国产在线| 欧美一区二区视频97| 99精品国产热久久91蜜凸| 一区二区三区在线观看视频| 亚洲国产精品一区制服丝袜| 欧美成人国产| 亚洲开发第一视频在线播放| 亚洲一区免费视频| 亚洲福利专区| 欧美一级理论性理论a| 久久国产精彩视频| 亚洲精品日产精品乱码不卡| 亚洲欧美电影院| 欧美高清在线一区二区| 国产私拍一区| 亚洲午夜av| 亚洲日本va在线观看| 久久久久久久网| 国产日本亚洲高清| 制服丝袜激情欧洲亚洲| 欧美www视频| 久久精品一二三| 国产精品免费观看视频| 一区二区三区精品在线| 欧美电影免费| 久久成人免费日本黄色| 国产精品国产馆在线真实露脸| 亚洲国产小视频在线观看| 久久深夜福利免费观看| 亚洲一区二区三区在线| 欧美日韩一区在线观看视频| 日韩亚洲欧美一区| 日韩视频中文字幕| 欧美女同视频| 亚洲精品久久| 亚洲国产美女| 国产精品99免费看 | 亚洲美女网站| 欧美三日本三级三级在线播放| 亚洲国产精品免费| 免费在线一区二区| 欧美jizz19hd性欧美| 日韩视频在线你懂得| 亚洲人午夜精品| 欧美 日韩 国产一区二区在线视频 | 久久男人资源视频| 在线观看视频免费一区二区三区| 久久手机免费观看| 免费国产一区二区| 亚洲视频自拍偷拍| 在线视频亚洲一区| 国产一区二区福利| 欧美成人精品不卡视频在线观看 | 国产精品永久免费| 久热精品在线视频| 麻豆精品91| 亚洲图中文字幕| 玖玖玖免费嫩草在线影院一区| 欧美激情精品久久久久久黑人| 国产精品ⅴa在线观看h| 久久久亚洲国产天美传媒修理工| 亚洲在线观看免费| 亚洲第一在线综合在线| 亚洲精品日韩精品| 国产欧美一区二区精品秋霞影院 | 男人天堂欧美日韩| 欧美日韩在线播放三区四区| 一区二区三区www| 性欧美超级视频| 亚洲第一视频| 亚洲一区二区三区视频| 韩国美女久久| 一本久久知道综合久久| 国产美女高潮久久白浆| 欧美肥婆在线| 国产日韩在线一区| 欧美激情一区二区久久久| 欧美午夜剧场| 亚洲激情第一区| 国产视频一区在线观看| 国产午夜精品视频免费不卡69堂| 久久九九久精品国产免费直播| 欧美成人免费一级人片100| 性做久久久久久久久| 欧美成人第一页| 久久精品欧洲| 国产精品ⅴa在线观看h| 免费视频一区| 国产一区二区三区久久久| 在线一区二区三区四区| 亚洲精品视频在线看| 久久精品一区蜜桃臀影院| 午夜在线观看欧美| 欧美成人精品福利| 免费成人网www| 狠狠干综合网| 久久精品理论片| 久久大综合网| 一本在线高清不卡dvd | 欧美偷拍另类| 亚洲国产高清在线观看视频| 国产精品日日摸夜夜添夜夜av| 亚洲激情欧美| 亚洲黄色精品| 亚洲一区亚洲| 亚洲一区国产| 欧美xxx成人| 欧美成人首页| 狠狠久久五月精品中文字幕| 中文国产成人精品久久一| 久久综合一区| 亚洲大胆美女视频| 伊人久久亚洲美女图片| 亚洲欧美国产制服动漫| aa级大片欧美三级| 欧美激情一区二区在线| 亚洲精品国产精品乱码不99按摩| 黑人操亚洲美女惩罚| 欧美一区二区黄| 久久久久免费观看| 国产日本欧美在线观看| 久久精品国产精品亚洲| 久久gogo国模裸体人体| 国产亚洲福利| 久久精品欧美| 亚洲国产欧美一区二区三区久久| 亚洲日本免费电影| 欧美伦理91i| 亚洲一区二区欧美| 性欧美1819sex性高清| 国产精品入口夜色视频大尺度| 亚洲综合日韩中文字幕v在线| 欧美亚洲视频一区二区| 国产亚洲欧美一区二区| 免费观看久久久4p| 一区二区日韩精品| 久久视频在线视频| 999亚洲国产精| 国产精品你懂的在线| 久久aⅴ国产欧美74aaa| av不卡免费看| 国产精品一区二区三区观看| 久久亚洲一区二区| 在线一区亚洲| 老司机免费视频一区二区三区| 国语自产精品视频在线看一大j8 | 正在播放日韩| 久久久久久久网| 影音国产精品| 欧美日韩国产系列| 亚洲免费在线| 91久久久久久| 久久久之久亚州精品露出| 亚洲精品日韩综合观看成人91| 欧美日韩国产成人在线| 午夜精品电影| 亚洲精品网站在线播放gif| 久久国产综合精品| 一本色道久久综合亚洲精品不卡| 国产欧美日韩一区二区三区| 免费在线观看精品| 午夜精品区一区二区三| 亚洲人成小说网站色在线| 久久国产高清| 亚洲欧美激情视频| 亚洲成色www8888| 国产区日韩欧美| 国产精品久久久久免费a∨| 久久字幕精品一区| 午夜日韩视频|