Page 1 of 1

[C++] Finding/reading a specific line in a file?

Posted: Sat Sep 05, 2009 4:04 pm
by JaxDragon
As many of you know, INI files are a popular way of storing program data. The ini format I'm looking to use looks like this

Code: Select all

ID = 1
Name = a1
Password = test
hSprite = 2
aSprite = 5
and so on and so forth. What I'm having trouble with though, is reading the data into variables. I don't know how to jump to a specific line, and take the value(after the =) and put it in a variable. Any help?

Re: [C++] Finding/reading a specific line in a file?

Posted: Sat Sep 05, 2009 4:46 pm
by sparda
Jax mahman! You have to write a parser. And before you write it, you need to design it ;)

So first, what are the syntax rules? Any syntax restrictions, comment character, etc.

You can "jump" to a specific line by addressing the newline characters encoded into the text (INI) file. With text files, I sparingly (albeit wrongly) read the whole file to a buffer, and indexed the addresses of the newline characters.

So read the file, look for a '\n' (newline) and do some programming around that. The way I do the reading into variables (C++) is by having a rule that says: "any value after '=' " is a variable. I would check the stream using istream.peek(), as opposed to istream.get(), which would "pop" off the character out of the stream buffer; then just copy bytes to the corresponding data type in your program.

Of course this is very much simplified and there are many other ways you can do it. I'm just mentioning one. Also, when messing with file reading/writing, it is good to have a way to confirm that bytes are read/written correctly, so have some driver programs ready as well as some hex dump utilities.

Re: [C++] Finding/reading a specific line in a file?

Posted: Sat Sep 05, 2009 5:56 pm
by JaxDragon
I have to write a parser? Curse my luck. Never had any experience writing one. Time to look at google :*(

Re: [C++] Finding/reading a specific line in a file?

Posted: Sat Sep 05, 2009 6:15 pm
by andrew
This looks really promising. :)

Re: [C++] Finding/reading a specific line in a file?

Posted: Sat Sep 05, 2009 6:32 pm
by JaxDragon
That looks very nice. Looking for "Alex"'s source code from the comments. I need that simplicity :|

Re: [C++] Finding/reading a specific line in a file?

Posted: Sat Sep 05, 2009 7:45 pm
by andrew
JaxDragon wrote:That looks very nice. Looking for "Alex"'s source code from the comments. I need that simplicity :|
Did you mean Alvaro?

Re: [C++] Finding/reading a specific line in a file?

Posted: Mon Sep 07, 2009 2:06 pm
by MarauderIIC
JaxDragon wrote:As many of you know, INI files are a popular way of storing program data. The ini format I'm looking to use looks like this

Code: Select all

ID = 1
Name = a1
Password = test
hSprite = 2
aSprite = 5
and so on and so forth. What I'm having trouble with though, is reading the data into variables. I don't know how to jump to a specific line, and take the value(after the =) and put it in a variable. Any help?
You could use a STL map. Read the line. Split on the "=". Store so that you have a key of "ID" and a value of "1". Then you can use some named constants to index into the map (for instance, const string ID = "ID"; const string NAME = "Name", etc) all the time, or you can extract them from the map to variables yourself (no, C++ can't go "oh, this string is Name, I need to make a string Name" or anything like that).

Code: Select all

const int NUM_MAP_INDEXES = 5;
const string[NUM_MAP_INDEXES] MAP_INDEXES = {"ID", "Name", "Password", "hSprite", "aSprite"};

map<string, string> loadedValues;

/* open file ... */
string line;
string::size_type location; //pretty much just an unsigned int

getline(file, line);
while (file) {
    location = line.find(" = ");
    if (location != string::npos)
        loadedValues[line.substr(0, location)] = line.substr(location + 1);
    getline(file, line);
}

int id;
string name;

for (int i = 0;i < NUM_MAP_INDEXES; ++i) {
    string val = loadedValues[MAP_INDEXES[i]];
    switch (i) {
        case 0:
            id = atoi(val.c_str());
            break;
        case 1:
            name = val;
            break;
    }
}
Might be one way to get the values from the map and put them into variables. Variables should probably be assigned as you read the file though, not after you've read the whole thing.