Notes of C + + primer Chapter 8 IO Library

  1. Iostream defines the basic types for reading and writing streams, fsstream defines the types for reading and writing named files, and ssstream defines the types for reading and writing memory string objects.
  2. The standard library enables us to ignore the differences between these different types of flows, which is implemented through the inheritance mechanism.
  3. Because we cannot copy IO objects, we cannot set formal parameters or return types to stream types. Functions that perform IO operations usually use theCitation MethodPass and return flow. Reading and writing an IO object will change its state, so the passed and returned references cannot be const
  4. IO library condition status
state explain
strm::iostate Strm is an IO type, iostate is a machine related type, which provides a complete function to express conditional state. The IO library defines four constexpr values of iostate types to represent specific bit patterns.
strm::badbit A binary value of 100 indicates that the stream has crashed
strm::failbit The binary value of 010 indicates that an IO operation failed
strm::eofbit The binary value of 001 indicates that the stream has reached the end of the file
strm::goodbit Used to indicate that the stream is not in an error state. This value is guaranteed to be zero
s.eof() If eofbit of stream s is set (set to 1), it returns true If the stream sfailbitorbadbitSet, returns true
s.bad() If badbit of stream s is set, true is returned
s.good() If the stream s is in a valid state, it returns true
s.clear() Reset all the conditional status bits in stream s (set to 0), and set the state of the stream to valid. Return void
s.clear(flags) According to the given flags flag bit, the corresponding condition state bit in stream s is set. The type of flags is strm:: iostate. Return void
s.setstate(flags) According to the given flags flag bit, the corresponding condition state bit in stream s is set. The type of flags is strm:: iostate. Return void
s.rdstate() Returns the current condition state of stream s, and the return value type is strm:: iostate
using namespace std;

istream& func(istream& is)
	int v;
	while (is >> v, ! is.eof ()) // stop reading until the end of the file is encountered
		if (is.bad())
			cerr << "Bad Error!\n";
		else if (
			cerr << "Wrong Data! Please try again!\n";
			is.ignore(1024, '\n');
		cout << v << endl;
	return is;

int main()
	return 0;
  1. Badbit represents a system level error, such as an unrecoverable read-write error. In general, once badbit is set, the stream can no longer be used. After a recoverable error occurs, the failbit is set, and a character is read when the value is expected to be read. This problem can usually be fixed and the stream can still be used. If it reaches the end of the file, eofbit and failbit will be set. The value of goodbit is 0, which indicates that the stream has no error. If badbit, failbit and eofbit are set, the condition for detecting the flow state will fail.
  2. When badbit is set, fail also returns true. This means that using good or fail is the right way to determine the overall state of the flow. In fact, the code we use as a condition is equivalent to!fail(). EOF and bad operations can only represent specific errors.
  3. The following code willfailbitandbadbitReset, but keepeofbitunchanged:
    //Reset the failbit and badbit to keep the other flag bits unchanged
      cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit);
      *The difference between clear and setstate:
      *Clear forcibly covers the conditional state of the current flow (whether it is 0 or 1) with an argument value
      *Setstate adds the parameter value (bit set to 1) to the conditional state of the current stream
  4. causeBuffer refreshThe reasons for this are as follows:
    • The program ends normally, and the buffer refresh is executed as part of the return operation of the main function.
    • When the buffer is full, the buffer needs to be refreshed before new data can be written to the buffer.
    • We can use the operator endl to flush the buffer explicitly
    • After each output operation, we can use the operator unitbuf to set the internal state of the stream to clear the buffer. By default, unitbuf is set for cerr, so the contents written to cerr are refreshed immediately.
    • One output stream may be associated with another stream. In this case, when the associated stream is read or written, the buffer of the associated stream is refreshed. For example, by default, both CIN and cerr are associated with cout, so reading CIN or writing cerr will cause the buffer of cout to be flushed.
  5. The operator endl completes the line feed and refreshes the buffer. Flush flushes the buffer, but does not output any additional characters. Ends inserts an empty character into the buffer('\0'), and then flush the buffer.
  6. If you want to refresh the buffer after each output operation, you can use the unitbuf operator. It tells the stream to perform a flush operation after each subsequent write operation. The nountbuf operator resets the stream to use the normal system managed buffer refresh mechanism
    Cout < unitbuf; // the buffer will be flushed immediately after all output operations
      //Any output is immediately refreshed without buffering
      Cout < nountbuf; // return to normal buffering mode
  7. If the program terminates abnormally, the output buffer will not be refreshed. When a program crashes, its output data is likely to stay in the output buffer waiting for printing.
  8. When an input stream is associated with an output stream, any attempt to read data from the input stream will refresh the associated output stream first.
  9. Interactive systems should usually associate input and output streams. This means that all output, including user prompts, will be printed before the read operation.
  10. There are two overloaded versions of tie: one without parameters that returns a pointer to the output stream. If the object is currently associated with an output stream, it will return a pointer to the stream. If the object is not associated with a stream, it will return a null pointer. The second version of tie takes a pointer to ostream, relates itself to ostream, and returns the output stream pointer of the previous binding.
  11. We can associate an istream object with another ostream or an ostream with another ostream. Each flow can be associated with at most one flow at the same time, but multiple flows can be associated with the same ostream at the same time
    cin.tie (& cout); // just for demonstration: the standard library associates CIN with cout
      // old_ Tie points to the stream (if any) currently associated with the CIN
      ostream *old_ tie =  cin.tie (nullptr); // CIN is no longer associated with other streams
      //The CIN was associated with cerr; This is not a good idea because CIN should be associated with cout
      cin.tie (& cerr); // reading CIN will refresh cerr instead of cout
      cin.tie (old_ // reconstruct the normal correlation between CIN and cout
  12. Fstream specific operations
operation explain
fstream fstrm; Create an unbound file stream. Fstream Is a type defined in the header file fstream
fstream fstrm(s); Create a fstream and open a file named s. S can be of type string or a pointer to a C-style string. These constructors are explicit. The default file mode depends on the type of fstream.
fstream fstrm(s, mode); Similar to the previous constructor, but opens the file in the specified mode Open a file named s and bind it to fstrm. S can be a string or a pointer to a C-style string. The default file mode depends on the type of fstream. Return void
fstrm.close() Close the file bound to fstrm. Return void
fstrm.is_open() Returns a bool value indicating whether the file associated with fstrm has been successfully opened and not yet closed
  1. Where base type objects are required, we can replace them with objects of inherited types. This means that a function that takes an iostream type reference (or pointer) parameter can be called with a corresponding fsstream (or ssstream) type.
  2. If the call to open fails, the failbit will be set. Because calling open may fail, it is usually a good habit to check whether open is successful.
    If (out) // check whether open is successful
               //Open is successful, we can use the file
  3. Once a file stream has been opened, it remains associated with the corresponding file. In order to associate a file stream with another file, you must first close the associated file. Once the file is closed successfully, we can open a new file.
    in.close () // close the file (ifile + "2"); // open another file
  4. When a fstream object is destroyed, close is called automatically.
  5. Each flow has an associatedFile modeTo indicate how to use a file.
pattern explain
in Open as read
out Open as write
app Navigate to the end of the file before each write operation
ate Navigate to the end of the file as soon as you open it
trunc truncate file
binary IO in binary mode
  1. The specified file mode has the following restrictions:
    • You can only set out mode on an OFSTREAM or fsstream object
    • In mode can only be set on ifstream or fsstream objects
    • The TRUNC mode can be set only when out is also set
    • As long as TRUNC is not set, you can set the app mode. In app mode, even if the out mode is not explicitly specified, the file is always opened as output
    • By default, even if we do not specify TRUNC, the file opened in out mode will be truncated. In order to keep the contents of the file opened in out mode, we must specify app mode at the same time, which will only append the data to the end of the file, or specify in mode at the same time, that is, open the file and read and write at the same time.
    • Ate and binary patterns can be used for any type of file stream object, and can be combined with any other file pattern.
  2. The only way to preserve existing data in a file opened by OFSTREAM is to explicitly specify the app or in mode
  3. Every time you open a file, you must set the file mode, either explicitly or implicitly. The default value is used when the program does not specify a mode.
  4. Operation specific to stringstream
operation explain
sstream strm; Strm is an unbound stringstream object. Ssstream is a type defined in the header file ssstream
sstream strm(s); Strm is an ssstream object that holds a copy of string s. This constructor is explicit
strm.str() Returns the copy of string saved by strm
strm.str(s) Copy string s to strm. Return void

using namespace std;

struct PersonInfo
	string name;
	vector phones;
int main()
	String line, word; // save the line and word from input respectively
	Vector people; // save all records from input
	istringstream record;

	while (getline(cin, line))
		Personainfo; // create an object to save the record data
		record.clear (); // when reusing a string stream, call clear every time
		record.str (line); // bind the record to the line just read in
		record >> ; // read the name
		While (record > > word) // read the phone number
			info.phones.push_ Back (word); // keep them
		people.push_ Back (info); // append this record to the end of people

	return 0;