开发者

sscanf() doesn't recognize format properly

开发者 https://www.devze.com 2023-01-23 21:30 出处:网络
When I use sscanf() in the following code, it is taking the whole line and placing it in the first string for some reason, and I do not see any problems with it. The output from Msg() is coming out li

When I use sscanf() in the following code, it is taking the whole line and placing it in the first string for some reason, and I do not see any problems with it. The output from Msg() is coming out like PatchVersion=1.1.1.5 = °?¦§-

The file looks like this (except each is a new line, not sure why it shows as one on StackOverflow)

PatchVersion=1.1.1.5
ProductName=tf
appID=440

Code:

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(subLin开发者_JAVA技巧e, "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;
}


One solution would be to use the (rather underused, in my opinion) character group format specifier:

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

Also, you should use the return value of sscanf() to verify that you did indeed get both values, before relying on them.


%s is "greedy", i.e. it keeps reading until it hits whitspace (or newline, or EOF). The '=' character is none of these, so sscanf just carries on, matching the entire line for the first %s.

You're probably better off using (for example) strtok(), or a simple character-by-character parser.


From the manpage of scanf, regarding %s:

Matches a sequence of non-white-space characters; the next pointer must be a pointer to character array that is long enough to hold the input sequence and the terminating null character ('\0'), which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first.


%s will read characters until a whitespace is encountered. Since there are no whitespaces before/after the '=' sign, the entire string is read.


Your use of arrays is very poor C++ technique. You might use streams but if you insist on using sscanf and arrays then at least use vector to manage your memory.

You might print out exactly what is in subLine and what Msg does. Is this your own code because I have never heard of FileHandle_t. I do know that it has a method that returns a char* that presumably you have to manage.

Regular expressions are part of the boost library and will soon be in the standard library. They are fairly "standard" and you might do well to use it to parse your line.

(boost::regex or tr1::regex if you have it, VS2008 has it)

0

精彩评论

暂无评论...
验证码 换一张
取 消