2009-07-12 106 views
1

比方說,我希望從中分離買逗號,這樣的標準輸入的項目清單:scanf可以識別字符串中的格式字符嗎?

item1, item2, item3,...,itemn 

,我也希望允許用戶發出項目和逗號之間的空格,所以這種投入是在我的程序合法:

item1,item2,item3,...,itemn 

如果我使用scanf這樣的:

scanf("%s,%s,%s,%s,...,%s", s1, s2, s3, s4,...,sn); 

將T當失敗這裏沒有空格(我測試過),因爲它會將整個輸入作爲一個字符串引用。那麼我怎樣才能解決這個問題,只有C標準庫函數?

回答

7

你可以看看strtok。首先讀取的行到緩衝區中,然後記號化:

const int BUFFERSIZE = 32768; 
char buffer[BUFFERSIZE]; 
fgets(buffer, sizeof(buffer), stdin); 

const char* delimiters = " ,\n"; 
char* p = strtok(buffer, delimiters); 
while (p != NULL) 
{ 
    printf("%s\n", pch); 
    p = strtok(NULL, delimiters); 
} 

然而,隨着strtok你需要知道的potential issues related to reentrance的。

+1

使用strtok_r()解決重新進入問題。如果你的平臺沒有strtok_r(),這裏有一個公有領域的實現:http://snipplr.com/view/16918/strtokr/ – 2009-07-12 21:12:11

8

快速回答永遠不會使用scanf來讀取用戶輸入。它旨在用於從文件中讀取嚴格格式化的輸入,即使這樣也不是很好。至少,你應該閱讀整行,然後用sscanf()解析它們,這給你一些機會來糾正錯誤。最好你應該寫你自己的解析函數

如果你真的在使用C++,請調查C++字符串和流類的用法,它們更加強大和安全。

2

我想最好是編寫自己的解析函數。但是如果你仍然喜歡scanf,儘管它有缺陷,你可以做一些解決方法,只需用%[^,\ t \ r \ n]替換%s即可。

%s匹配非空白字符序列的問題,所以它也吞下逗號。因此,如果將%s替換爲%[^,\ t \ r \ n],它將幾乎相同(不同之處在於%s使用isspace(3)來匹配空格字符,但在這種情況下,您明確指定了哪些空格字符匹配和這個列表可能與isspace不一樣)。

請注意,如果您希望允許逗號前後的空格,則必須爲格式字符串添加空格。格式字符串「%[^,\ t \ r \ n],%[^,\ t \ r \ n]」匹配「hello,world」,「hello,world」,「hello,world」等字符串。

+1

呃,我不認爲正則表達式在`scanf`中工作。 – GManNickG 2009-07-12 20:40:38