I need to implement a mechanism where I can initialize a vector of my custom class using a text source, where each line of the source is representing one instance of my class. To achieve this, I implemented the operator >> for my class and stringstream. When I read the source, I go line-by-line and get a substream of my original source, then parse the substream each time. This has three benefits for me. First, this way I can make sure that one line of the text source would represent exactly one instance of my class. Second, as the rest of the line after parsing is ignored, I can safely add any comment in any line of my text source, which would surely get ignored by the parser. And third, I don’t need to mention the length of the vector in my original source, since the first time I get a parsing error (I check the fail and bad bits of the stream to confirm this) I know that the vector declaration is over.
To parse line-by-line, I’m using the following code:
std::stringstream fullStream;
std::stringstream lineStream;
std::string str;
bool isValid;
myClass newInstance;
std::vector < myClass > result;
// Fill fullStream from external source (codepart omitted)
isValid = true;
while ( isValid && ! fullStream.eof ( ) ) {
std::getline ( fullStream, str );
lineStream.clear ( );
lineStream.str ( str );
lineStream >> newInstance;
isValid = ! lineStream.fail ( );
if ( isValid ) {
result.push_back ( newInstance );
}
}
Although this code works fine, I’m wondering if there was a better way to achieve the same result. Specially, if there was a more efficient way to extract a line from fullStream to lineStream.
Thanks,
Ádám
One obvious alternative would be to have your
operator>>do line-by-line reading itself, so you don’t have to do that externally:With that, code to read data from a file becomes a little more straightforward:
Edit: if you don’t want to build the line-oriented reading directly into the
operator>>forMyClass, another possibility is to use a proxy class:Then when you want to do line-oriented reading, you read objects of the proxy class, but store objects of the original class:
But, when/if you want to read a stream of objects instead of lines of objects, you use the object’s own
operator>>directly: