2012-12-04 57 views
1

我需要使用以下格式「foo =%d」解析c中的字符串,我需要檢查格式是否正確並讀取int值。使用sscanf控制整個字符串

我最初的代碼是:

int foo_set = 0; 
int foo; 
if (sscanf(text, "foo=%d", &foo) == 1) 
    foo_set = 1; 

但代碼應該拒絕輸入諸如 「富= $ 5%£」。 這段代碼能工作嗎?

int foo_set = 0; 
int foo; 
char control; 
if (sscanf(text, "foo=%d%c", &foo, &control) == 1) 
    foo_set = 1; 

使用control字符代碼檢查沒有額外的輸入。 有沒有更好/更正確的方法來做到這一點?

感謝

+1

'這個代碼能工作嗎?'。你爲什麼不跑來看? – axiom

回答

6

使用%n格式說明,以確定處理結束,並檢查它的字符串的長度相匹配:

const char* text = "foo=4d"; 
int pos; 
int foo; 

if (sscanf(text, "foo=%d%n", &foo, &pos) == 1 && 
    pos == strlen(text)) 
{ 
    /* Valid as all of text consumed. */ 
} 

說明的格式說明n C99標準:

沒有輸入消耗。 相應的參數應該是一個指向 的有符號整數,其中將寫入從 輸入流中讀取的字符數,該數字是通過調用fscanf函數到目前爲止。執行 %n指令不會增加在執行fscanf函數完成時返回的賦值計數。沒有參數被轉換, 但一個被消耗。如果轉換規範包含禁止 字符或字段寬度的分配,則行爲未定義。

查看演示https://ideone.com/d1rhPf

+1

我不知道這是真的還是最新的,但根據Linux的'scanf'手冊頁:'C標準說:「執行%n指令不會增加完成時返回的賦值計數執行「,但更正似乎與此相矛盾。對於%n轉化對回報價值的影響,可能不要做任何假設 – interjay