2010-11-05 140 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有它)