Thread: Playing with .ini files.

  1. #1
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964

    Playing with .ini files.

    I decided to try and start playing a bit with parsing strings and .ini files. This is what i have come up with so far:

    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    std::string parse (std::string bar, int num, int size);
    
    int main()
    {
        std::ifstream ini ("C:\\inifile.ini");
        std::string foo, bar;
        int size = 0;
        int choice;
        ini >> foo;
        size = foo.length();
    
        std::cin >> choice;
        
        bar = parse(foo, choice, size);
        
        std::cout << bar;
        std::cin.ignore();
    }
    
    std::string parse (std::string bar, int num, int size)
    {
                int i = 0, j = 0;
                std::string foo;
                bool equal = false;
                
                switch(num)
                {
                case 1:
                     for(i; i < size; i++)
                     {
                            if(bar[i] == '=')
                            {
                                      equal = true;
                                      break;
                            }
                            else
                            {
                                      equal = false;
                            }
                     }
                     if(!equal)
                     {
                              std::cerr << std::endl << "Ini file formatting is invalid";
                              std::cin.ignore();
                              exit(1);
                     }
                break;
                      
                case 2:
                     for(i; i < size; i++)
                     {
                            if(bar[i] == '=')
                            {
                                      for(j; j < i; j++)
                                      {
                                             foo[j] = bar[j];
                                      }
                            }
                     }
                break;
                
                case 3:
                     for(i; i < size; i++)
                     {
                            if(bar[i] == '=')
                            {
                                      j = size;
                                      for(j; j > i; j--)
                                      {
                                             foo[j] = bar[j];
                                      }
                            }
                     }
                break;
                
                default:
                        std::cerr << std::endl << "Parsing error encountered.";
                        std::cin.ignore();
                        exit(1);
                break;
                }
                return(foo);
    }
    I apologize for the very crude code, i realize that i am using poor variable names but i don't have a vivid imagination and i'm just trying to get it to work, i can always make it pretty afterwards.

    The idea is to get the user to input a choice, 1 - 2 or 3.

    1 Checks the ini file for a "=".
    2 Scans all text before the "=".
    3 Scans all text after the "=".

    If 1 is inputted, then the "foo" string returned from my function will just contain either 1 or 0. Or atleast, that's how it's supposed to be, but no matter what i do, it just prints '0', and the 2 other cases just prints a blank string.

    I realize that i'm only parsing the first line of the file, i have checked the stream from the file and it's fine, so that's not the problem, it's somewhere in my code im guessing.

    The contents of the .ini file im using is simply:

    Code:
    varname = varvalue
    I've gone through it a few times and i can't really find the problem, can you guys please have a shot at it?

    Again, sorry for the ugly code, i know that poor indentation is not very popular on this board.

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    You are indexing into a string called foo, but you create it with a default constructor, which means that all indices are invalid (the string storage doesn't/may not exist). May-be you should append characters to the empty string.

    There are also string functions that are able to find '=' characters in the string, and I think stringstream should be able to extract the portion up to the '=' character (getline with delimiter '=').

    Edit:
    By the way
    Code:
    ini >> foo;
    only reads up to the first whitespace. Use getline to read whole lines.

    With stringstreams you could do something like that
    Code:
    #include <string>
    #include <sstream>
    
    /* 
        Parses line, returns id and value by reference
        Returns whether successful
    */
       
    bool parse(const std::string& line, std::string& id, std::string& value)
    {
        std::stringstream ss(line);
        return std::getline(ss, id, '=') //id read successfully
            && std::getline(ss, value) //value read successfully
            && value.find('=') == std::string::npos //value doesn't contain '='
            && ss.eof(); //nothing left to read (unneeded if line is really one line)
    }
    Last edited by anon; 06-20-2007 at 08:48 AM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    You don't need to pass the length of foo into the function (your size parameter), as you know, the string object has the length member function that returns its own length. Just pass the string itself into the function and use the length member function where necessary.

    Aside from the comment already given above, nothing in case 1 does anything to create a "1" or "0" return string as you require.

    Some suggestions...

    Checking for a given character in a string (use the find member function):
    Code:
    string test("varname = varvalue");
    string::size_type index = test.find('=');
    if( index != string::npos )
    {
        // We found an = character at position given by index
    }
    else
    {
        // No = character found
    }
    Getting the before and after strings (use the above index result and combine that with the substr function):
    Code:
    string before = test.substr(0,index);
    string after = test.substr(index+1);
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  4. #4
    Registered User kroiz's Avatar
    Join Date
    Jun 2007
    Posts
    116
    if you are doing this for excersize then it is one thing.
    but if you are planning to use that in a real program a better desgin IMHO would be to create a XSD and bind it to your program with something like Code Synthesis.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Program Deployment and DLL/OCX Files?
    By dfghjk in forum C++ Programming
    Replies: 5
    Last Post: 06-16-2008, 02:47 AM
  2. Folding@Home Cboard team?
    By jverkoey in forum A Brief History of Cprogramming.com
    Replies: 398
    Last Post: 10-11-2005, 08:44 AM
  3. Playing wma files
    By maxorator in forum C++ Programming
    Replies: 4
    Last Post: 10-02-2005, 02:23 AM
  4. Batch file programming
    By year2038bug in forum Tech Board
    Replies: 10
    Last Post: 09-05-2005, 03:30 PM
  5. playing .mmf files
    By Ruski in forum Windows Programming
    Replies: 2
    Last Post: 06-17-2005, 09:49 PM