views:

50

answers:

1

I'm trying to read the contents of a text file into the attributes of a class. The file is structured in such a way that each line contains all the information needed for one object of the class. One line might look like:

TYC 9537 00066 1 341.76920751 -88.32499920  8.762  9.294 mc1 hd 210531        0.385   8.80 P F5 5  6440  F5 V

What I have been doing is read the line from the file to a stream with getline(), in a function like so:

void LoadFile( std::vector<TycDat*> & target , std::fstream & source )
{
    std::string line ;
    while( std::getline( source , line ) )
    {
        target.push_back( new TycDat ( line ) ) ;
    }
}

Where TycDat is the name of the class, target is the Vector I'm storing it in, and source is the file stream already pointed to the file.

Within the constructor for TycDat I created a std::istringstream associated to the std::string parameter line and used the >> operator to read the values in order into the attributes. This worked for the most part. I had to create a few char arrays to be able to read some of them, where hd 210531 for example corresponds to one string which the >> operator would have split.

My real issue came with one of the last parts, in the example the 8.80 P F5 5 6440. Where it says F5 are in fact two values, a letter and a number, that I need to store separately as a char and an int. Moreover, the int at the end might not always be there.

What I'm doing right now is, after reading the P correctly:

std::string aux_ ;
iss >> aux_ ;
TClass = aux_[0] ;    //     Temperature class (7)
if ( aux_.size() > 1 ) SClass = std::atoi( aux_.data()+1 ) ;  // SubClass

I don't like that, mostly because I'm making a new string. But I couldn't figure out how to make it work correctly. The problem is in splitting the word apart (I guess I could ignore one character and then use TClass = iss.get() to get TClass, but I don't know how to check that the next value exists before reading it in.

Hmm, I could peek to look for a value different from ' ', then use the >> operator....

Well, I'll try that I guess and let you know how it goes. Thanks for the help. Any other comments are appreciated. I feel bad about erasing the question after writing all this.

A: 

My suggestion would be to have a look at Boost.Spirit. It will allow you to express the format of your input string naturally, and will make future changes easier if (when!) the input format changes. As a bonus, it'll run much faster at runtime! http://www.boost.org/doc/libs/1_44_0/libs/spirit/doc/html/spirit/introduction.html Good Luck

usta