-
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:
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.
-
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
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)
}
-
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);
-
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.