2010-11-05 306 views
0

當我在下面的代碼中使用sscanf()時,由於某種原因,它將整行放在第一個字符串中,並且我沒有發現任何問題。從消息()的輸出是走出像PatchVersion=1.1.1.5 = °?¦§-sscanf()無法正確識別格式

文件看起來是這樣的(除了每個是一個新行,不知道爲什麼它顯示了一個在計算器上)

PatchVersion=1.1.1.5 
ProductName=tf 
appID=440 

代碼:

bool ParseSteamFile() 
{ 
    FileHandle_t file; 
    file = filesystem->Open("steam.inf", "r", "MOD"); 

    if(file) 
    { 
     int size = filesystem->Size(file); 
     char *line = new char[size + 1]; 

     while(!filesystem->EndOfFile(file)) 
     { 
      char *subLine = filesystem->ReadLine(line, size, file); 

      if(strstr(subLine, "PatchVersion")) 
      { 
       char *name = new char[32]; 
       char *value = new char[32]; 
       sscanf(subLine, "%s=%s", name, value); 

       Msg("%s = %s\n", name, value); 
      } 
      else if(strstr(subLine, "ProductName")) 
      { 
       char *name = new char[32]; 
       char *value = new char[32]; 
       sscanf(subLine, "%s=%s", name, value); 

       Msg("%s = %s\n", name, value); 
      } 
     } 

     return true; 
    } 
    else 
    { 
     Msg("Failed to find the Steam Information File (steam.inf)\n"); 
     filesystem->Close(file); 
     return false; 
    } 

    filesystem->Close(file); 
    return false; 
} 
+2

以供將來參考,*請*發表最小的代碼示例,即再現錯誤最小編譯代碼(你大約4行可以做這個例子)。這使得其他人更容易閱讀,並且您可能會在過程中發現錯誤。 – 2010-11-05 13:02:05

回答

0

從scanf的的手冊頁,關於%S:

匹配的非空白字符的序列;下一個指針必須是一個指向字符數組的指針,該指針的長度足以容納輸入序列和終止的空字符('\ 0'),該字符會自動添加。輸入字符串在空白處或最大字段寬度處停止,以先發生者爲準。

2

%s是「貪婪的」,即它一直持續閱讀直到它遇到whitspace(或換行符或EOF)。 '='字符不是這些,所以sscanf只是進行,匹配整個行的第一個%s

您可能最好使用(例如)​​或簡單逐個字符的解析器。

+0

或者可以嘗試使用boost :: regex。 – CashCow 2010-11-05 13:03:49

+0

或者線程安全的strtok_r() – mmatloka 2010-11-05 13:05:36

+0

即使std :: string和find也會這樣做。 – CashCow 2010-11-05 13:53:10

0

%s將讀取字符,直到遇到空格。由於在'='符號之前/之後沒有空格,因此將讀取整個字符串。

4

一個解決方案是使用(相當未充分利用的,在我看來)字符組格式說明:

sscanf(subLine, "%[^=]=%s", name, value); 

此外,你應該使用的sscanf()的返回值來驗證你確實拿到這兩個值,依靠他們之前。

0

您對數組的使用很差C++技術。你可能會使用流,但如果你堅持使用sscanf和數組,那麼至少使用vector來管理你的內存。

您可能會精確地打印出subline中的內容以及Msg的作用。這是你自己的代碼,因爲我從來沒有聽說過FileHandle_t。我知道它有一個方法返回一個char *,這可能是你必須管理的。

正則表達式是boost庫的一部分,很快會在標準庫中。他們是相當「標準」的,你可以用它來解析你的線。

(升壓::正則表達式或TR1 ::正則表達式,如果你擁有它,VS2008有它)