I want to learn how to read and write config files. Are there any good tutorials on this topic? I mainly need help with the file reading/saving part. I know how to use fstream for simple tasks but that is about it...
I've tried google but with no luck...
Last edited by McCain; Feb 17th, 2003 at 07:30 PM.
Never argue with fools, they will only drag you down to their level, and beat you with experience.
Q: How do you tell an experienced hacker from a novice?
A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer
I wasn't thinking about any specific file format right now. First I want more generic knowledge, but my goal is the LiteStep Step.RC format.
But as I said, for now I just want simple stuff. Like saving preferences for a program.
Never argue with fools, they will only drag you down to their level, and beat you with experience.
Q: How do you tell an experienced hacker from a novice?
A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer
Well, you simply have properties and assigned values. The simplest format would be something like:
width = 12
height = 23
color = (255,0,0)
You only need to parse those strings then (use strtok or sscanf in C, stringstream or the boost string tokenizer library in C++).
Writing is even simpler, a cout or printf does the trick (or ofstream and fprintf in this case of course).
All the buzzt CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
What does "parse" mean?
If it means something like "get" would I get each line of the config file in to different strings, so if I had 10 lines, I would have 10 strings?
If I have a string that says "width = 12" how do I cut that "width = " part of? Or would it be easier to just read the 12 part of the line? how would I do that?
Never argue with fools, they will only drag you down to their level, and beat you with experience.
Q: How do you tell an experienced hacker from a novice?
A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer
"Webster's Revised Unabridged Dictionary (1913)"
Parse Parse, v. t. imp. & p. p. Parsed; p. pr. & vb. n.
Parsing. L. pars a part; pars orationis a part of speech.
See Part, n. (Gram.)
To resolve into its elements, as a sentence, pointing out the
several parts of speech, and their relation to each other by
government or agreement; to analyze and describe
grammatically.
So in this case, it means to decompose a string into its component parts. Such as:
Code:
i = (5,3,2)
This can be parsed into something more specific, such as a vector with name i, and components 5, 3, and 2.
I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You". -- Linus Torvalds
You'd split at the = to get two substrings: "width " and " 12". You trim the spaces away and map the first string against the second (using an STL map or something like that).
I've got a class that reads such a file, but it is in C#.
And yeah, each line into it's own string.
For the color, the third substring would be "(255,0,0)", which you would have to split again: strap away the parentheses -> "255,0,0" and split at , which results in the three substrings "255", "0" and "0" which can easily be interpreted as RGB components of a color.
Last edited by CornedBee; Jan 27th, 2003 at 06:30 AM.
All the buzzt CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
I'm nearly done with an extremly cool template-and-C++-standard-library-based configuration file class but I've got a little template problem. Posted a thread about it.
All the buzzt CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
Here it is. The namespace config_files contains two important things for the casual user: configfile and wconfigfile.
I'll write up a small documentation for it.
All the buzzt CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
You'd split at the = to get two substrings: "width " and " 12".
And yeah, each line into it's own string
So, do I get one or two strings from this line?
You'd split at the = to get two substrings: "width " and " 12".
How do I split the strings at the =?
If these questions are answered(sp?) in your example, never mind my questions... But mind you, I've only just started with learnig classes and I don't know what a template is/how to use it...
I'll download the example when I get time, probably tomorrow
Thanks for all your help so far
Never argue with fools, they will only drag you down to their level, and beat you with experience.
Q: How do you tell an experienced hacker from a novice?
A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer
What I posted isn't an example, it's a fully functional group of classes that you won't understand without a good knowledge of templates and the C++ standard library.
It uses multiple inheritance, and one of the base classes is a template parameter
Of course, VC++ gets confused. VC++6 won't compile it, don't even try. VC++7 forgets to call a constructor, but I directly included a workaround.
Anyway.
Here's how to parse in pseudo-code:
Code:
while(NOT end_of_file(file_handle)) {
string line = get_line(file_handle);
trim(line);
string_array ar = split_string(line, '=');
trim(ar[0]); trim(ar[1]);
property_map.add(ar[0], ar[1]);
}
Here's a version of split_string that compiles in VC++6:
Code:
// this takes a string and splits it into an array of smaller strings
// it's splitted every time split_at is encountered
void split_string(const string &s, vector<string> & out, char split_at)
{
// for searching the string
string::const_iterator stay, run;
// set stay to the start of the string
stay = s.begin();
// temporary
string t;
// loop run through the string, from front to back
for(run=stay; run != s.end(); ++run)
{
// if encountered split char...
if(*run == split_at)
{
// ...clear the temporary value...
t.erase();
// (speeds it up a little)
t.reserve(run-stay);
// ..., copy current substring to temporary...
t.append(stay, run);
// ...and add it to the array.
out.push_back(t);
// Finally, let the next substring begin directly after the splitting char.
stay = run+1;
}
}
// same as above for the last piece (from last split char to end of string)
t.erase();
t.reserve(run-stay);
t.append(stay, run);
out.push_back(t);
}
And here's a version I like more (because I love to treat a string as a container), but it only compiles in VC++7:
Code:
// this takes a string and splits it into an array of smaller strings
// it's splitted every time split_at is encountered
void split_string(const string &s, vector<string> & out, char split_at)
{
// for searching the string
string::const_iterator stay, run;
// set stay to the start of the string
stay = s.begin();
// temporary
string t;
// loop run through the string, from front to back
for(run=stay; run != s.end(); ++run)
{
// if encountered split char...
if(*run == split_at)
{
// ...clear the temporary value...
t.clear();
// (speeds it up a little)
t.reserve(run-stay);
// ..., copy current substring to temporary...
copy(stay, run, back_inserter(t));
// ...and add it to the array.
out.push_back(t);
// Finally, let the next substring begin directly after the splitting char.
stay = run+1;
}
}
// same as above for the last piece (from last split char to end of string)
t.clear();
t.reserve(run-stay);
copy(stay, run, back_inserter(t));
out.push_back(t);
}
I wrote the second version first, then found out it doesn't compile in 6 and made some changes.
All the buzzt CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
You could improve those by making split_at a string itself, and using each character as a separate delimeter. Then you could simply split_string(..., std::string(" ="));, and forget the trims.
Ive built a quick and dirty string_tokenizer class for this purpose, works quite nicely, if anyone would like it.
Thank you guys for all those lines of code, I'll try to understand as much of it as I can and then get back to you if I have any further questions (I'm sure I will...)
Thanks again
Never argue with fools, they will only drag you down to their level, and beat you with experience.
Q: How do you tell an experienced hacker from a novice?
A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer
Of course, VC++ gets confused. VC++6 won't compile it, don't even try
That's what I use... Ahh, well, guess it doesn't matter all that much just yet, all the code I write right now is so simple even the worst compiler could probably compile it...
Never argue with fools, they will only drag you down to their level, and beat you with experience.
Q: How do you tell an experienced hacker from a novice?
A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer
Right now I have a config file for a program I'm running (LiteStep) that's 450 lines long, one configuration setting on each line. If I read all those lines into different strings and then split the strings in two parts, one for the text and one for the actual value, I'll end up with 900 strings... That can't be good...
Another problem is that there's no way of knowing in what order the lines are in, so if I want to change one setting I'll have to search every line untill I find the one that I want and then edit it.
So I don't know how to go about doing this...
Any ideas anyone?
Right now everyone who uses this program has to edit the config files manually using a regulat text editor, but I want to write a graphical one, using dropdown menus and stuff...
Never argue with fools, they will only drag you down to their level, and beat you with experience.
Q: How do you tell an experienced hacker from a novice?
A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer
LiteStep uses modules (.dll files) and each moduel has its own settings. Each module has >30 settings and there's about 100 modules. That's 30*100 = 3000 names and each name has a value, so that's 6000 strings. And since I have no idea what modules a user might have loaded I can't know what settings to load and which not to load. So do I have to define 6000 strings or is there another way?
Every config file begins with information on what modules are loaded, and each module has an xml file that says what config-command it supports. Is it possible to dynamicly create string variables based on this information so I don't create more variables than nessesary?
Never argue with fools, they will only drag you down to their level, and beat you with experience.
Q: How do you tell an experienced hacker from a novice?
A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer
But that would require a rewrite of all the modules.
I think I'll just allow for modification of one module at a time, that way I only need about 30 strings at one time. I'll just search through the file and save the starting position of all modules-config and then load from the file on demand from the user...
Never argue with fools, they will only drag you down to their level, and beat you with experience.
Q: How do you tell an experienced hacker from a novice?
A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer