2014-09-18 199 views
0

我想讓getopt與我的C程序一起工作,但是我發現它不工作。 這裏是行不通getopt立即退出循環

char* getFlagArg(int argc, char **argv, char flag) { 
extern char *optarg; 
extern int optind, optopt, opterr; 
char opt; 
char options[3] = {flag,':',0}; 
while((opt = getopt(argc, argv, options)) != -1) { 
    if(opt == flag) 
     return optarg; 
} 
return ""; 
} 

當我運行這段代碼,它會立即退出循環(循環不運行,即使一次)的功能。我無法弄清楚爲什麼會發生這種情況。我已經證實argc,argv和options是我所期望的。思考?謝謝,麻煩您了!

+1

「我已經證實,argc,argv和選項都是我所期望的。」 - 你期望他們是什麼? – mafso 2014-09-19 00:05:36

+0

從代碼中,它表明你正試圖找到一個特定的標誌選項。什麼是用來啓動程序的命令行?當你輸入這個函數時,'optind'的值是多少?當函數退出時,'optind'的值是多少? – 2014-09-19 00:52:30

+0

命令行顯示「./a。出-u用戶文件名的argc,argv的「在程序 年底通過 OPTIND == 3‘和選項都是什麼,我希望他們是’我的意思是ARGC = 4,ARGV =」 ./a。去」,‘-u’,‘用戶’,‘文件名’],和標誌=‘U’,所以參數都獲得通過在正確的。 – Nero144 2014-09-19 01:26:03

回答

1

我試圖讓在這個問題的意見的觀點是這樣的:

char *arg; 

arg = getFlagArg (argc, argv, 'b'); 
printf ("-b arg = %s\n", arg); 
arg = getFlagArg (argc, argv, 'u'); 
printf ("-u arg = %s\n", arg); 

如果有一個名爲getFlagArggetopt已經,第二個電話很可能會失敗。想象一下你有一個選項-b,它接受了一個參數,命令行是./a.out -u foo -b quux filename。由於您先搜索-boptind將爲5,並且搜索-u將失敗,因爲optind大於1,這是值optind必須在我提供的示例命令行中找到-u選項。

您將需要通過將optind設置爲1來「重置」getopt。當然,如果這不是問題,我們需要看到代碼爲getFlagArg

編輯

選項沒有參數被允許在同一argv元件。 getopt可以處理此問題,但如果您有兩個選項-a-c./a.out -cau foo將與getopt一起使用,但在找到-a後,即使再次將optind設置爲1,也不一定找到-c。只有在您通過-u foo(或任何其他需要參數的選項)後,您才能重置optind並重新開始解析。

FreeBSD和其他一些BSD克隆提供了一個非標準optreset變量來處理這種情況。但是,在Linux上Glibc不會,所以要小心這種奇怪的「怪癖」getopt

+1

+1這非常像試圖通過多次讀取「FILE *」而不將內部指針重新設置迴文件開頭。我通常會看到人們在一個'while'循環中抓住* all *命令行參數,從而避免了這個問題。 – turbulencetoo 2014-09-19 16:34:15

+0

非常感謝你,這是問題所在。我想我不明白的man page正確/夠細心: _The調用者可以將其重置爲1重啓相同的argv掃描,掃描或有了新的說法,當vector_ – Nero144 2014-09-19 17:40:52

+0

@ Nero144高興它幫助。在我的編輯中解釋了將'optind'設置回1的一個警告,就好像它是一個「重置按鈕」一樣,所以請閱讀並注意它只適用於_do不需要參數的選項。 @turbulencetoo也提供了一些有用的建議。 – 2014-09-19 19:38:19

0

這應該是int opt而不是char c,因爲它是由getopt()返回的整數值。你不會給你使用的C版本;所以很難做一個測試來驗證你所得到的行爲,但假設在這種情況下,從intchar,然後再回到int的轉換等於-1

當然,如果您更改opt的聲明,您還應該更改您的代碼,並使用正確的鑄件進行比較,值爲flag,後面緊跟着下面的值。

+0

感謝您的建議,但劇組並沒有解決這個問題。我用gcc 4.6.3(不我使用它的C版本的答案?)上的x86_64的Ubuntu Linux系統。 – Nero144 2014-09-19 01:32:18

+0

你怎麼使用的意思Cast?您是否試圖將getopt的結果轉換爲char?geto pt()返回一個int,如果這個int不是-1,那麼它可以轉換成char。我提到的演員陣營是「如果(選擇==標誌)」,你必須在行後,並且必須改變,如果你改變聲明從char到int。我沒有gcc 4.6.3或Ubuntu,所以我無法測試這個,但其餘的代碼看起來不錯。但是,argc,argv和flag的傳輸值可能是錯誤的,因此應在運行時檢查這些值。 – SylvainL 2014-09-19 04:17:48