I have a question that concerns how C++ input streams (istream, ifstream, istringstream, etc.) behave using the extraction (>>) operator when at the end of a stream's contents.
For instance, I have an input file which is just a one-line string: "do_stuff 20060101 " (yes, that is a trailing space)
I'm using a parse function that attempts to extract a string ("do_stuff") and a long ("20060101") by using some code roughly equivalent to:
Expand|Select|Wrap|Line Numbers
- while(myStream.good() && !myStream.eof()) {
- string nextName;
- long nextID;
- myStream >> nextName >> nextID;
- //pass on this data, rinse, and repeat
- //...
- }
<do_stuff, 20060101> < , 20060101>
How do streams handle whitespace at their end? Do they read an empty string after that? What is the explanation for the behavior I'm seeing?
Also, I'm fully aware that I'm a total newb with C++, yet I know this method is incredibly flawed and lacking robustness. I know full well what I need to do; I'm just not sure how to do that in the best way using built-in stream functions. For instance what are the proper ways to test that:
a) a stream still contains more tokens (or better yet, non-empty tokens)
b) a given extraction succeeded, and if not, why?
Not that it should matter (I'm only using standard C++ language/lib features), but I'm writing in MacOSX.4, using g++ v4.0.1.
Note also that this is not a homework assignment, nor am I interested primarily in a solution to my bug (though I do want to fix it). I want to understand how this feature works and how it is used properly. Any caveats/nuances/tips/tricks that anybody would like to share would be greatly appreciated!
Thanks so much,
-losingToTheDevil
P.S. The entire method code is posted below. If more code is needed to answer my questions, please let me know.
Expand|Select|Wrap|Line Numbers
- //re-construct queue from file stream
- TodoQueue::TodoQueue(ifstream& aInstream)
- {
- //common initializer for all constructors
- init();
- ListNode* current = head;
- while(aInstream.good() && !aInstream.eof()) {
- string nextJobName;
- long nextJobDeadline;
- //read the next two tokens from the file
- aInstream >> nextJobName >> nextJobDeadline;
- //debugging code REMOVE THIS
- cout << "Next job: " << nextJobName << ", " << nextJobDeadline;
- current->pNext = new ListNode(nextJobName, nextJobDeadline);
- //job queue has one more job in it
- size++;
- current = current->pNext;
- }
- }