Why do we need iostream? We have been using C ++ input and output for various exercises since the very beginning, and the input and output are provided by the iostream library, so it is necessary to discuss this standard library, it is different from the stdio library of C language. From the very beginning, it uses multi-inheritance and virtual inheritance to implement an object-oriented hierarchy. It is provided to programmers as a standard library component of C ++.
Iostream provides input and output support for built-in type objects and file input and output. The class designer can expand the iostream library, to support custom input/output operations.
Why is expansion required to provide support? Here is an example.
# Include <stdio. h ># include <iostream> using namespace STD; Class test {public: Test (int A = 0, int B = 0) {test: A = A; test :: B = B ;}int A; int B ;}; int main () {test T (); printf ("% ??? ", T); // The output format scanf (" % ??? ", T); // The input format cout is not clear <t <Endl; // It is also not clear about CIN> T; // system ("pause ");}
In the code above, whether you use C-style input and output, or the input and output of C ++ are not explicit, because the C language does not have an operator overload mechanism, the stdio library cannot be extended. Therefore, printf () and scanf () cannot support extended recognition of custom class objects, c ++ can use the operator overload mechanism to expand the iostream library so that the system can identify custom types, so that the input and output can clearly know what they are doing and what the format is.
In the preceding example, printf and cout are used to compare the differences between C and C ++ in processing input and output, from the far-reaching input and output of C, we can see that it is a function call method, while C ++ is an object mode. cout and CIN are ostream and istream objects.
1 iostream: istream and ostreamThe iostream library in C ++ mainly contains the following header files:
Iosstream Library |
Fstream |
Iomainip |
IOS |
Iosfwd |
Iostream |
Istream |
Ostream |
Sstream |
Streambuf |
Strstream |
The input and output operations we are familiar with are provided by the istream (input stream) and ostream (output stream) classes. To allow two-way input/output, the iostream class is derived from istream and ostream.
For the inheritance relationships of classes, see:
The iostream library defines the following three standard stream objects:
- Cin, indicating the istream Class Object of the standard input. Cin allows us to read data such as data from devices.
- Cout indicates the ostream Class Object of standard output. Cout allows us to output or write data to the device.
- Indicates the osttream Class Object of the standard error. Cerr is the place where program error messages are exported. It can only write data to screen devices.
The output is mainly completed by the overloaded left shift operator (<), and the input is mainly completed by the overloaded right shift operator (>:
- > A indicates to put data into object.
- <A indicates to extract the data stored in object.
These standard stream objects all have the default corresponding devices, as shown in the following table:
C ++ Object Name |
Device Name |
Standard Device Name in C |
Default meaning |
CIN |
Keyboard |
Stdin |
Standard Input |
Cout |
Display Screen |
Stdout |
Standard output |
Cerr |
Display Screen |
Stderr |
Standard Error output |
The table above indicates that the default input device of the CIN object is the keyboard, and the default output device of the cout object is the display screen.
In principle, how does C ++ use the CIN/cout object and the left-and right-shift operator overload to implement input and output?
The following uses the output as an example to describe its implementation principle:
- Cout is an object of the ostream class. because it points to a standard device (display screen), it is defined as a global object in the iostream header file.
- Ostream cout (stdout); // The standard device name in C to which it points by default. It is used as a parameter of its constructor.
- In the header file of iostream. H, each basic data type of the ostream class has its friends function to overload the Left shift operator.
- Ostream & operator <(ostream & temp, int source );
- Ostream & operator <(ostream & temp, char * PS );
- ... And so on
An output statement: cout <"www.cndev-lab.com";, actually called is ostream & operator <(ostream & temp, char * PS); this operator reloads the function, because the returned Stream object is referenced, the reference can be used as the left value, so when the program has a similar cout <"www. cndev-lab.com "<" China Software Development Lab "; when such a statement appears, it can constitute continuous output.
The iostream library not only supports the input and output of objects, but also the input and output of file streams. Therefore, before you reload the left-shift and right-Shift Operators in detail, we need to first understand the input and output controllers of the file.
2 fstream: ifstream and ofstream
The input and output classes related to files are mainly in fstream. h. This header file is defined. In this header file, three classes are defined. These three classes control various input and output operations on the file, they are ifstream, ofstream, and fstream. The fstream class is derived from the iostream class. The Inheritance relationships between them are shown in.
Because the file device is not a standard default device like the display screen and keyboard, it is in fstream. the H header file contains no pre-defined global objects like cout, so we must define an object of this class by ourselves, to output information to a file (that is, writing data to a file) using a file as a device, use the ofstream class.
The default constructor of the ofstream class is:
ofstream::ofstream(const char *filename,int mode = ios::out,int openprot = filebuf::openprot);
- Filename: name of the file to be opened
- Mode: how to open the file
- Prot: Open File Attributes
The following table lists the options of mode and openprot:
Mode Attribute Table |
IOS: app |
Open an object in append Mode |
IOS: ATE |
After the file is opened, it is located at the end of the file. IOS: app contains this attribute. |
IOS: Binary |
Open a file in binary mode. The default mode is text. For the differences between the two methods, see the previous article. |
IOS: In |
Open the file as input |
IOS: Out |
Open the file as an output |
IOS: trunc |
If the file exists, set the file length to 0. |
You can use "or" to connect the preceding attributes, for example, IOS: Out | IOs: binary.
Openprot Attribute Table |
Attribute |
Description |
0 |
Normal file, open access |
1 |
Read-Only files |
2 |
Implicit File |
4 |
System Files |
You can use "or" or "+" to connect the above attributes. For example, 3 or 1 | 2 means opening the file with read-only and implicit attributes.
The instance code is as follows:
# Include <fstream> using namespace STD; int main () {ofstream myfile ("C: \ 1.txt", IOS: Out | IOs: trunc, 0 ); myfile <"China Software Development Laboratory" <Endl <"url:" <"www.cndev-lab.com"; myfile. close () system ("pause ");}
After using the file, you can use the close member function to close the file.
IOS: The append mode is app. It is a good habit to judge the File status when append mode is used.
Example:
# Include <iostream> # include <fstream> using namespace STD; int main () {ofstream myfile ("C: \ 1.txt", IOS: app, 0); If (! Myfile) // or write myfile. Fail () {cout <"failed to open the file. The target file may be in read-only status! "; System (" pause "); exit (1);} myfile <" China Software Development Lab "<Endl <" url: "<" www.cndev-lab.com "<Endl; myfile. close ();}
When defining ifstream and ofstream class objects, we can also leave the file unspecified. In the future, you can use the member function open () to explicitly connect a file to a class object.
For example:
# Include <iostream> # include <fstream> using namespace STD; int main () {ofstream myfile; myfile. open ("C :\\ 1.txt", IOS: Out | IOs: app, 0); If (! Myfile) // or write myfile. Fail () {cout <"file creation failed. The disk cannot be written or the file is read-only! "; System (" pause "); exit (1);} myfile <" China Software Development Lab "<Endl <" url: "<" www.cndev-lab.com "<Endl; myfile. close ();}
Next, let's take a look at how to use the ifstream class object to read the data in the file and then output it to the standard device.
The Code is as follows:
# Include <iostream> # include <fstream> # include <string> using namespace STD; int main () {ifstream myfile; myfile. open ("C :\\ 1.txt", IOS: In, 0); If (! Myfile) {cout <"file read error"; System ("pause"); exit (1) ;}char ch; string content; while (myfile. get (CH) {content + = CH; cout. put (CH); // cout <ch; this write is also possible} myfile. close (); cout <content; System ("pause ");}
In the above example, we use the member function get () to read valid characters in the file one by one, and then use the put () member function to output the data in the file to the standard device (screen) One by one through a loop) the get () member function returns a false value when the file is read to the end of the silence, so we can use this feature as the termination condition of the while loop, we also introduced the C ++ string type in the above example. It is saved to the content one by one during loop reading. To use the string type, it must contain the string type. h header file.
After briefly introducing the ofstream class and ifstream class, let's take a look at the fstream class. The fstream class is derived from iostream, And the fstream class object can perform read and write operations on files.
The sample code is as follows:
# Include <iostream> # include <fstream> using namespace STD; int main () {fstream myfile; myfile. open ("C :\\ 1.txt", IOS: Out | IOs: app, 0); If (! Myfile) {cout <"file write error. The file attribute may be read-only! "<Endl; System (" pause "); exit (1) ;}myfile <" China Software Development Lab "<Endl <" url: "<" www.cndev-lab.com "<Endl; myfile. close (); myfile. open ("C :\\ 1.txt", IOS: In, 0); If (! Myfile) {cout <"file read error, the file may be lost! "<Endl; System (" pause "); exit (1) ;}char ch; while (myfile. get (CH) {cout. put (CH);} myfile. close (); System ("pause ");}
Because the fstream class can read and write files at the same time, you must explicitly specify the mode and openprot parameters when starting the object.
Next, let's take a look at the basic knowledge of streaming. What is streaming?
3 strstream: ostrstream and istrstreamA simple understanding is the ability to control the input and output classes of string type objects. c ++ not only supports C ++-style string stream control, but also supports C-style string stream control.
Let's take a look at how C ++ controls the C-style string stream. The string in C is actually a character array, data in the character array is arranged consecutively in the memory. We usually use the char STR [size] or char * STR statement to create a C-style character array, to enable the character array as a device and provide input and output operations, C ++ introduces three classes: ostrstream, istrstream, and strstream. To use these classes to create objects, strstream must be included. h header file.
- The istrstream class is used to perform input operations on a C-style stream. It uses a string array as the input device.
- The ostrstream class is used to perform the output operations of a C-style stream, that is, an array of strings as the output device.
- The strstream class also supports the input and output operations of C-style streaming.
The istrstream class is derived from istream (input stream class) and strstreambase (string stream base class). ostrstream is derived from ostream (output stream class) and strstreambase (string stream base class, strstream is derived from iostream (input and output stream class) and strstreambase (string stream base class.
Shows their inheritance relationships:
Streaming is also not a standard device and does not have pre-defined global objects. Therefore, you cannot directly operate on streaming. You need to create objects using constructors.
The constrfunction of istrstream class is as follows:
istrstream::istrstream(const char *str,int size);
Parameter 1 indicates the string array, and parameter 2 indicates the array size. When the size is 0, the istrstream class object is directly connected to the memory space pointed by STR and ended with \ 0.
The following sample code uses the istrstream class to create a class object. It sets the stream input device as a string array and uses it to input data to a class object. The Code is as follows:
#include <iostream>#include <strstream>using namespace std;int main(){char *name = "www.cndev-lab.com";int arraysize = strlen(name)+1;istrstream is(name,arraysize);char temp;is>>temp;cout<<temp;system("pause");}
Ostrstream class is used to execute streaming output. Its constructor is as follows:
ostrstream::ostrstream(char *_Ptr,int streamsize,int Mode = ios::out);
The first parameter indicates the character array, the second parameter indicates the size of the array, and the third parameter indicates the open mode.
Here is an example code:
# Include <iostream> # include <strstream> using namespace STD; int main () {int arraysize = 1; char * pbuffer = new char [arraysize]; ostrstream ostr (pbuffer, arraysize, IOS: Out); ostr <arraysize <ends; // when outputting data to a stream object using ostrstream, use ends to end the string cout <pbuffer; delete [] pbuffer; System ("pause ");}
In the code above, we create a C-style streaming output object ostr, we successfully output the data in arraysize to the heap space of the pbuffer pointer pointed to by the ostr object in the form of a string. pbuffer is also the string array to be output, use ends to end the string at the end. If you do not do this, there is a risk of overflow.
4 stringstreamFor stringstream, I don't need to talk about it. As you know, it is used for input and output of C ++-style strings. Stringstream constructor prototype is as follows:
stringstream::stringstream(string str);
The sample code is as follows:
#include <iostream>#include <sstream>#include <string>using namespace std;int main(){stringstream ostr("ccc");ostr.put('d');ostr.put('e');ostr<<"fg";string gstr = ostr.str();cout<<gstr<<endl;char a;ostr>>a;cout<<asystem("pause");}
In addition, the stringstream class object is also commonly used for conversion between string and various built-in data types. The sample code is as follows:
# Include <iostream> # include <sstream> # include <string> using namespace STD; int main () {stringstream SSTR; // -------- int to string ----------- int A = 100; string STR; SSTR <A; SSTR> STR; cout <STR <Endl; // -------- string to Char [] -------- SSTR. clear (); // if you want to convert multiple types by using the same stringstream object, you must call the clear () member function after each conversion. String name = "colinguan"; char cname [200]; SSTR <name; SSTR> cname; cout <cname; System ("pause ");}
Next, let's learn about the input/output status signs.
5 io_state indicates the input/output status.The Input/Output System in C ++ contains records about the results of each input/output operation. The current status information is contained in an io_state object. Io_state is an enumeration type (just like open_mode). The following is the value it contains.
- Goodbit no error
- Eofbit has reached the end of the file
- Failbit non-fatal input/output error, recoverable
- A badbit fatal input/output error cannot be recovered
There are two ways to obtain the input/output status information. One way is to call the rdstate () function, which returns the error mark of the current status. For example, if there is no error, rdstate () will return goodbit. The following example shows the usage of rdstate:
# Include <iostream> using namespace STD; int main () {int A; CIN> A; cout <cin. rdstate () <Endl; If (CIN. rdstate () = IOs: goodbit) {cout <"the type of the input data is correct, no error! "<Endl;} If (CIN. rdstate () = ios_base: failbit) {cout <" input data type error, non-fatal error. You can clear the input buffer to recover it! "<Endl;} system (" pause ");}
Another method is to use any of the following functions to check the corresponding input/output status:
bool bad();bool eof();bool fail();bool good();
The following example shows the usage of the above member functions:
# Include <iostream> using namespace STD; int main () {int A; CIN> A; cout <cin. rdstate () <Endl; If (CIN. good () {cout <"the input data type is correct, no error! "<Endl;} If (CIN. Fail () {cout <" input data type error, non-fatal error. You can clear the input buffer to recover it! "<Endl;} system (" pause ");}
If an error occurs, the stream status is marked as an error. You must clear the error status so that your program can continue running properly. To clear the error status, use the clear () function. This function includes a parameter, which is the flag value you want to set as the current state ., You only need to use IOs: goodbit as the real parameter.
The sample code is as follows:
#include <iostream>using namespace std;int main(){int a;cin>>a;cout<<cin.rdstate()<<endl;cin.clear(ios::goodbit);cout<<cin.rdstate()<<endl;system("pause");}
When we find that the input is incorrect and needs to be corrected, use clear () to mark it as correct, and also use the get () member function to clear the input buffer, to achieve Repeated input.
The sample code is as follows:
# Include <iostream> using namespace STD; int main () {int A; while (1) {CIN> A; If (! CIN) // The condition can be rewritten to CIN. Fail () {cout <"incorrect input! Enter "<Endl; cin. Clear (); cin. Get () ;}else {cout <A; break ;}} system (" pause ");} again ");}
Finally, an example of how to handle the error mark of the file stream is provided. The Code is as follows:
# Include <iostream> # include <fstream> using namespace STD; int main () {ifstream myfile ("C: \ 1.txt", ios_base: In, 0 ); if (myfile. fail () {cout <"failed to read the file or the specified file does not exist! "<Endl;} else {char ch; while (myfile. get (CH) {cout <ch;} If (myfile. EOF () {cout <"all file content has been read" <Endl;} while (myfile. get (CH) {cout <ch ;}} system ("pause ");