Not logged in, Join Here! or Log In Below:  
 
News Articles Search    
 

 Home / General Programming / c++ question Account Manager
 
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.
 
David Olsson

March 24, 2005, 11:45 AM

I'm currently parsing some text files with a fgets/sscanf combo.
Text lines consists of a few patterns like (name, int, name, int int) or (int, name, constant string, int) and so on.
So basicly what I do is simply reading a line with fgets and then try out several sscanf combinations

fgets(s, 256, fp);
if(sscanf(s, "%s %i %s %i %i", ...) == 5)
{
....
}
else if(sscanf(s, "%i blahblahblah %s %i", ...) == 3)
{
....
}
else if...

and so on.
Then I tried to do the same thing with c++ streams and not using sscanf and got stuck. I've been looking for a solution all day, reading lots and lots of info on the net but found nothing. It's really bugging me. So now I challenge anyone to come up with a simple solution or is it even possible?

 
Reedbeta

March 24, 2005, 01:21 PM

I don't have much experience with using the STL for text I/O, but maybe something like this would work:

  1. std::ifstream myfile("somefile.txt");
  2. std::stringstream cur_line;
  3. myfile.get(cur_line.rdbuf(), 'n');  // Reads a line from the file into the stringstream
  4.  
  5. // Check first combination
  6. cur_line >> string_var1 >> int_var1 >> string_var2 >> ...;
  7. // Check if it worked - operator >> sets the EOF bit if it came to the end of the string
  8. if ((cur_line.rdstate() & std::ios::eofbit) == 0)
  9. {
  10.      // Do stuff
  11. }
  12.  
  13. // Check second combination
  14. cur_line.rdbuf().seekpos(0);  // Reset the "file pointer" to the beginning of the string
  15. cur_line >> int_var1 >> int_var2 >> ...;
  16. // etcetera


You may find the stringstream class useful - it basically lets you read and write from a string like a stream.

As a general tip for working with streams and related things, go into the MSDN and familiarize yourself with the basic_ios, basic_istream, basic_ostream and basic_streambuf classes. Many of the useful classes like ifstream, ofstream, stringstream and others are derived from these.

 
Chris

March 24, 2005, 01:47 PM

Google for "boost" and "spirit". Once I understood the basics behind the spirit parser, it was the most wondeful tool I could have found for parsing purposes.

 
David Olsson

March 24, 2005, 01:57 PM

But still, how can it be so simple with sscanf and so hard with the c++ standard library excluding sscanf.

 
David Olsson

March 24, 2005, 02:21 PM

Yeah, I've been looking into strings streams today and realized that the solution probably need to use them. Is there function that let you skip a constant string or do you have to write one yourself ?

I think !cur_line is better to use than checking for eof
Btw does seekpos reset the flags ?

I know printf/scanf class of functions have problems with for example typesafety but I can't help thinking that they are so comfortably to work with.

 
Reedbeta

March 24, 2005, 02:31 PM

I don't know if seekpos resets the flags, I assumed that it does. If not you can set them yourself, I think the function is called setstate. I don't know about skipping a constant string, maybe you just have to read it into a string variable.

I'm in agreement with you about the C++ stream library though. I have never used it for working with files in an actual app. Most of the files I am interested in are binary, anyways. I have found stringstream useful for some kinds of parsing tasks (e.g. breaking up a comma delimited string) but that is about it.

 
This thread contains 6 messages.
 
 
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.