2017-04-20 19 views
-3
#include <stdio.h> 

int main() 
{ 
    char * msg = "Internal power 10. power sufficient. total count 10"; 
    char * temp = "Internal power %d. power %s. total count %d"; 
    int v1, v2, ret; 
    char str1[64]; 
    ret = sscanf(msg, temp, &v1, str1, &v2); 

    printf("%d\n", ret); 
    printf("%d %s %d ", v1, str1 , v2); 

    return 0; 
} 

我想知道爲什麼sscanf失敗,爲什麼它不能夠檢索最後一個變量?sscanf的行爲是不同的

+3

由於'%s'讀取''.'中的'.',所以格式字符串中的點的文字匹配失敗。您需要使用掃描集'%[^。 ]'只讀'足夠'的數據。 –

+0

@JonathanLeffler嗨,我明白了,但是可以幫助我知道如何使用sscanf()和scan set []實現它,並且限制是我無法更改傳入消息及其模板。 – user7375520

+1

如果你不能修改'模板'(我認爲你的意思是格式字符串),那麼你就卡住了。你有什麼不會工作;有些事情必須改變才能使其發揮作用。也許你需要澄清你在評論中提出的問題。下面有個很好的答案。 –

回答

7

%s讀取空格 -defined字符串;也就是說,它在到達點時消耗sufficient.,其餘格式". total count %d"與餘下的" total count 10"不匹配。

既然你期待的單詞所應遵循.,你還不如用%63[^.]即最多63個字符,做包括一個點。或%63[a-z]最大63個ASCII小寫字母 - 指定寬度明確也保證了緩衝區溢出不可能發生:

char * temp = "Internal power %d. power %63[^.]. total count %d"; 

附:總是檢查*scanf的返回值 - 它告訴有多少匹配符匹配(在這種情況下它應該是3);但是,現在返回2意味着第二次轉換後匹配失敗。

+0

謝謝,在這種情況下,你能告訴我如何獲得第三個變量嗎? – user7375520

+0

@ user7375520如本答案所述,將'power%s'改爲'power%63 [^。]'或'power%63 [a-z]'? –

+0

限制是我無法改變傳入消息及其模板。 – user7375520

3

的問題是scanf格式字符串的這一部分:"power %s."

問題是因爲scanf格式字符串是不是真的正則表達式或以其他方式做精確匹配。當你有"%s"格式,然後scanf(和它的兄弟姐妹)將讀取的一切直到下一個空格。

以字符串意味着你有"%s"會導致您的通話sscanf閱讀"sufficient."包括點。然後,調用將嘗試匹配已經讀入字符串的點,並且由於不再可用,調用將失敗。

您可以使用Jonathan Leffler in his comment建議的設置。我還建議你閱讀例如this scanf (and family) reference瞭解更多詳情。

+2

掃描集怎麼樣? –

+0

@JonathanLeffler確實,這應該可以正常工作。 –

+0

@Someprogrammerdude限制是我不能改變傳入消息及其模板。並且不能使用scanf()(scan set []),因爲該字符串是非STDIN的一部分。 – user7375520