> What I'm having some trouble understanding in your post is your consume function,
> and what it's supposed to be doing, as well as your overloaded >> function.
Let us say we have this object:
VideoGame ernie { "Alpha Beam With Ernie", "Edutainment", 'B', "Michael Callahan" } ;
And we write it to a file with:
file_streamm << ernie << '\n' ;
Looking at our
operator<< ()
, we can see that the text written into the file would be:
Title: Alpha Beam With Ernie
Genre: Edutainment
Rating: B
Developer: Michael Callahan |
Now, the job of our
operator>> ()
is to read in to an object, this text written out by our
operator<< ()
.
The steps we have to perform are:
1 2 3 4 5 6 7 8
|
a. verify that the first line starts with the tag "Title:"
b. if yes, read the rest of the line, after leaving a space, to get the title
c. verify that the second line starts with the tag "Genre:"
d. if yes, read the rest of the line, after leaving a space, to get the genre
e. verify that the third line starts with the tag "Rating:"
f. if yes, read the character, after leaving a space, to get the rating
g. verify that the last line starts with the tag "Developer:"
h. if yes, read the rest of the line, after leaving a space, to get the developer
|
If all the above steps are successful, modify the object with the information that has been read
Otherwise, indicate that an error occurred by putting the stream into a failed state.
If we look at the above, we can see that steps
a,
c,
e and
g have a lot in common; the only variance is that the tags are different for the different steps.
This common task is what
static bool consume( std::istream& in, const char* expected )
does.
As input, it is given the stream and the expected tag.
If the expected tag is found, it 'consumes' the tag (extracts it, removes it from the stream) and returns true.
If it is not found, it returns false.
1 2 3
|
std::string str ;
// try to read (consumes) the next string, and return true if it is the expected tag
return in >> std::ws >> str >> std::ws && str == expected ;
|
The only other thing it does is to skip (or consume) the space(s) immediately after the tag with
>> std::ws. This is something we have to do after each tag and it is convenient to have our consume function do it for us.
Once this much is understood,
operator>> is a breeze:
1 2 3 4 5 6 7 8
|
if( consume( in, VideoGame::title_tag ) && // if we have successfully consumed the tag "Title:"
std::getline( in, title ) && // and we have successfully read the rest of the line into title
consume( in, VideoGame::genre_tag ) && // and we have successfully consumed the tag "Genre:"
std::getline( in, genre ) && // and we have successfully read the rest of the line into genre
consume( in, VideoGame::rating_tag ) && // and we have successfully consumed the tag "Rating:"
in >> rating && // and we have successfully read the next character into rating
consume( in, VideoGame::developer_tag ) && // and we have successfully consumed the tag "Developer:"
std::getline( in, developer ) ) // and we have successfully read the rest of the line into developer
|
we have read all the information correctly, update the object with the data that was read
1 2 3 4
|
{
// read everything succesfully, set the state of the game object
game = { title, genre, rating, developer } ;
}
|
if not, our attempt to read has failed, indicate failure by putting the stream into a failed state
1 2 3 4 5 6
|
else
{
// read failed
in.setstate( std::ios::failbit ) ; // indicate input failure
game = {} ; // optional: clear all the fields in the the game object
}
|
> Is the if statement starting on line 64 just reading user input,
> or is it somehow verifying that the correct user input was gathered?
Our
operator>>()
does not attempt to read input typed in by the user; it attempts to read what was written out by our
operator<<()
> Also I see that you initialized VideoGame objects,
> but how would this work to have the objects initialized based off of user input.
That part was left undone in the code originally posted.
1 2
|
// read values typed in by the user, with prompts and error recovery
bool read_from_stdin() ; // TODO
|
Let us take it one step at a time; this is a fair amount to digest at one time. Try to understand what has been done in
operator>>()
. Once we are clear with that, we can take up the next question: how would we accept input typed in by the user, and initialize an object with that input, handling errors in input, giving feedback to the user, prompting for re-entry of incorrect information etc.