I have been modding Valve games for quite a while, but one that I have never been good at in the least is using the char arrays to manipulate strings. I would REALLY like to improve considering how much time I waste on them. Obviously using proper Strings would be nice, but since all of the SDK functions return char *, or take it as args, it doesn’t make much since to convert back and fourth. Does anyone have any good links as far as understanding them better? Most of what I find on Google has just been snippets.
Also, I am trying to parse a very simple text file. Basically the contents look like this…
PatchVersion=1.1.1.2
ProductName=l4d
appID=440
I want to get the PatchVersion and ProductName. My code looks something like this, but really just make lack of proper knowledge has left me stumped. strtok only retrieves the token prior to the ‘=’ sign, strchr gives me a pointer to the location of it, but just don’t know a good method.
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);
Msg("SUBLINE: %s\n", subLine);
char *buffer = "";
if(strstr(subLine, "PatchVersion"))
{
char *c = strtok(subLine, "=");
while(c != NULL)
{
Msg("Token: %s\n", c);
c = strtok(subLine, "=");
}
}
}
}
}
There’s nothing wrong with using C-strings. It will however require you to write quite a bit of very low-level code, which has already been abstracted away when using String objects.
In general, a C-String is just an array of bytes (each byte corresponding to the ascii value of a character) with a null byte at the end. The actual syntax of the commands however can be a little esoteric, I recommended cplusplus.com as a reference.
Your second call to strtok needs to be called with null, rather than the subLine again:
At the moment you are tokenizing by the equals sign, so you will end up with:
Don’t forget that strtok consumes the input string, so subLine will be empty once your loop finishes.
I would begin by tokenizing the string by spaces to get each key-value pair. Then I would split each key-value pair into it’s constituent elements and store the needed ones. The (s)scanf function can do this type of parsing very well. To read one pair into
nameandvalue:You may then use strncpy to copy the value into the appropriate location. sscanf does not consume the input, so subsequent calls will have to move the pointer of subLine to beyond the previous match (or use three %s=%s pairs in the format expression, along with three name and value variable pairs, if you know there will always be three).
The important thing is to get your application code as far away from the low level operations as is reasonable. If you do this type of manipulation often, finding or creating a library which parses files such as this might be a good (and fun) idea.