If you know exactly what you’re dealing with and want to move the bytes directly into a variable, an array, or a structure in memory, you can use the unformatted I/O function read( ). The first argument is a pointer to the destination memory, and the second is the number of bytes to read. This is especially useful if you’ve previously stored the information to a file, for example, in binary form using the complementary write( ) member function for an output stream (using the same compiler, of course). You’ll see examples of all these functions later.
Handling stream errors
The Date extractor shown earlier sets a stream’s fail bit under certain conditions. How does the user know when such a failure occurs? You can detect stream errors by either calling certain stream member functions to see if an error state has occurred, or if you don’t care what the particular error was, you can just evaluate the stream in a Boolean context. Both techniques derive from the state of a stream’s error bits.
Stream state
The ios_base class, from which ios derives,[40] defines four flags that you can use to test the state of a stream:
Flag | Meaning |
badbit | Some fatal (perhaps physical) error occurred. The stream should be considered unusable. |
eofbit | End-of-input has occurred (either by encountering the physical end of a file stream or by the user terminating a console stream, such as with Ctrl-Z or Ctrl‑D). |
failbit | An I/O operation failed, most likely because of invalid data (e.g., letters were found when trying to read a number). The stream is still usable. The failbit flag is also set when end-of-input occurs. |
goodbit | All is well; no errors. End-of-input has not yet occurred. |
You can test whether any of these conditions have occurred by calling corresponding member functions that return a Boolean value indicating whether any of these have been set. The good( ) stream member function returns true if none of the other three bits are set. The eof( ) function returns true if eofbit is set, which happens with an attempt to read from a stream that has no more data (usually a file). Because end-of-input happens in C++ when trying to read past the end of the physical medium, failbit is also set to indicate that the "expected" data was not successfully read. The fail( ) function returns true if
Once any of the error bits in a stream’s state are set, they remain set, which is not always what you want. When reading a file for example, you might want to reposition to an earlier place in the file before end-of-file occurred. Just moving the file pointer doesn’t automatically reset eofbit or failbit; you have to do it yourself with the clear( ) function, like this:.
myStream.clear(); // Clears all error bits
After calling clear( ), good( ) will return true if called immediately. As you saw in the Date extractor earlier, the setstate( ) function sets the bits you pass it. It turns out that setstate( ) doesn’t affect any other bits—if they’re already set, they stay set. If you want to set certain bits but at the same time reset all the rest, you can call an overloaded version of clear( ), passing it a bitwise expression representing the bits you want to set, as in:.
myStream.clear(ios::failbit | ios::eofbit);
Most of the time you won’t be interested in checking the stream state bits individually. Usually you just want to know if everything is okay. This is the case when you read a file from beginning to end; you just want to know when the input data is exhausted. In cases such as these, a conversion operator is defined for void* that is automatically called when a stream occurs in a Boolean expression. To read a stream until end-of-input using this idiom looks like the following:.
int i;
while (myStream >> i)
cout << i << endl;