C++ : input / output stream

Time:2022-6-5

The input and output of data flow from one place to another like a water flow. This process is called “flow”.

(1) Input and output strategies for C and c++

The data source of the input stream may be a keyboard or a file.

The IO policies in C are as follows:

Use scanf (), gets () and other functions to read data from the keyboard, and use printf (), puts () and other functions to output data to the screen;
Use fscanf(), fgets() and other functions to read the data in the file, and use fprintf(), fputs() and other functions to write data to the file;

The IO policies in c++ are as follows:

The IO solution of C can also be used in c++;
Use functions such as CIN to read data from the keyboard, and use functions such as cout to output data to the screen;
For c++ file operations, you need to use the stream class, use the ifstream class to read the data in the file, and use the OFSTREAM class to write data to the file;
The fsstream class can either read data from a file or write data to a file.

The derivation system of input / output stream is as follows:

C++ : input / output stream

image.png

The functions of these flow classes are:

Istream: commonly used to receive data input from the keyboard;
Ostream: commonly used to output data to the screen;
Ifstream: used to read the data in the file;
OFSTREAM: used to write data to a file;
Iostream: it inherits from istream and ostream classes, because the functions of this class can be used for both input and output;
Fsstream: it combines the functions of ifstream and OFSTREAM classes. It can not only read the data in the file, but also write data to the file.

Two objects commonly used in c++cinandcout, which are defined in the <iostream> library and are built-in objects of c++.
Their common usage is:

int n;
Cout < < "please enter a number:";
cin >> n;
Cout < < input number is: < n < < endl;

becausecinandcoutIt is not a keyword, but an object, so you can call the member function of the object.

cinThe member functions of are:

Legal name of member function
getline(str,n,ch) Receive n-1 characters from the input stream to the str variable. When the specified ch character is encountered, it will stop reading. By default, ch is’\0′.
get() A character is read from the input stream, and the character disappears from the input stream.
gcount() Returns the number of characters extracted from the input stream last time. This function is often used in conjunction with get (), getline (), ignore (), Peek (), read (), readsome (), putback (), and Unget ().
peek() Returns the first character in the input stream, but does not extract it.
putback(c) Put the character c into the input stream (buffer).
ignore(n,ch) Characters are extracted from the input stream one by one, but the extracted characters are ignored and not used until n characters are extracted, or the currently read character is ch.
operator>> Overloads the > > operator to read data of the specified type and return the input stream object itself.

coutThe member functions of are:

Legal name of member function
put() Output a single character.
write() Outputs the specified string.
tellp() Gets the position of the current output stream pointer.
seekp() Sets the position of the output stream pointer.
flush() Flushes the output stream buffer.
operator<< Overloads the < < operator to output data of the specified type.

In addition,cerrandclog, which are also built-in objects of c++ and output objects, andcout, including member functions.
They andcoutThe difference is:

(1) Cout can output the data to the screen, and also output the data to the specified file through redirection;
     Neither cerr nor clog supports redirection. They can only output data to the screen;
(2) Both cout and clog have buffers, that is, when they output data, they will put the data to the buffer first, and will not display all the data on the screen until the buffer is full or when the line breaks manually (using the line break character'\n'or endl);
     Cerr, on the other hand, does not have a buffer and outputs data directly to the screen.
(2) Output string

usecoutObject can output strings,coutIt is an ostream object. You can output a single character by calling the put function. The code is as follows:

cout.put('A');

The return value of the put function is ostream, so if you want to output multiple letters, you can write this:

cout.put('A').put('B').put('C');

So, how do I output a string?

This can be achieved by calling the write function. The code is as follows:

cout.write(str, 1);

Write has two parameters. The first parameter is the string to be output, and the second parameter is the number of characters before the output string.

The return value of the write function is ostream, so it can be called continuously:

cout.write(str, 1).write(str, 2);
(3) Output current output stream pointer position

Call the output stream tell method to obtain the pointer position of the current output stream, which is generally used for file operations:

//File output stream object
ofstream outfile;
outfile. open("test.txt"); //  Open the file. If the file does not exist, create a new one
const char* str = "zhangsan";
for (int i = 0; i < strlen(str); i++) {
    outfile. put(str[i]); //  Output a character to a file
    long pos = outfile. tellp(); //  Get current output stream pointer position
    cout << pos << " ";
}
cout << endl;
outfile. close(); //  Close flow

The output is:

1 2 3 4 5 6 7 8
(4) Jump of output stream pointer position

Generally, if 1 character is output, the output stream pointer position will be automatically +1; if n characters are output, the output stream pointer position will be automatically +n.

Using the output streamseekpFunction to jump the output stream pointer.

seekpThe function is used to specify the position of the next character entering the output buffer. The demonstration code is as follows:

//File output stream object
ofstream outfile;
outfile. open("test.txt"); //  Open the file. If the file does not exist, create a new one
const char* str = "zhangsan";
for (int i = 0; i < strlen(str); i++) {
    outfile. put(str[i]); //  Output a character to a file
    if (i == 2) 
    {
        outfile.seekp(10);
    }
}

test. Txt file:

C++ : input / output stream

image.png

You can print the current pointer position with the tell function. The code is as follows:

//File output stream object
ofstream outfile;
outfile. open("test.txt"); //  Open the file. If the file does not exist, create a new one
const char* str = "zhangsan";
for (int i = 0; i < strlen(str); i++) {
    outfile. put(str[i]); //  Output a character to a file
}
Cout < < current output stream pointer position: << outfile tellp() << endl;

outfile. seekp(4); //  Change the output stream pointer position to 4, and the next output starts from 4

Cout < < current output stream pointer position: << outfile tellp() << endl;

outfile. seekp(40); //  Change the output stream pointer position to 4

Cout < < current output stream pointer position: << outfile tellp() << endl;

outfile. close(); //  Close flow

The output is:

Current output stream pointer position: 8
Current output stream pointer position: 4
Current output stream pointer position: 40

Seekp also has a function with two formal parameters. The usage is as follows:

//File output stream object
ofstream outfile;
outfile. open("test.txt"); //  Open the file. If the file does not exist, create a new one
const char* str = "zhangsanlisi";

for (int i = 0; i < strlen(str); i++) {
    outfile. put(str[i]); //  Output a character to a file
}

Cout < < current output stream pointer position: << outfile tellp() << endl;

outfile. seekp(4, ios::cur); //  Offset 4 units from the current position in a positive direction

Cout < < current output stream pointer position: << outfile tellp() << endl;

outfile. seekp(-4, ios::end); //  Offset 4 units in the negative direction from the end position

Cout < < current output stream pointer position: << outfile tellp() << endl;

outfile. seekp(4, ios::beg); //  Offset 4 units in the positive direction from the starting position

Cout < < current output stream pointer position: << outfile tellp() << endl;

outfile. close(); //  Close flow

The first parameter of seekp is the offset, which can be either a positive integer or a negative integer. Positive or negative indicates the offset direction.
The second parameter is the offset position. There are three acceptable values:

Ios:: beg offset from start position
Ios:: cur offset from current position
Ios:: end offset from end

The final output of the above code is:

Current output stream pointer position: 12
Current output stream pointer position: 16
Current output stream pointer position: 8
Current output stream pointer position: 4
(5) Cout formatted output

Ostream class can realize formatted output. The member functions related to ostream format are:

Member function explain
flags(fmtfl) The current format status is all replaced with fmtfl. Note that fmtfl can represent one format or multiple formats.
precision(n) Set the precision of the output floating-point number to n.
width(w) Specifies that the output width is w characters.
fill(c) When the output width is specified, it is filled with the character c when the output width is insufficient (filled with spaces by default).
setf(fmtfl, mask) Add fmtfl format to the current format and delete mask format. The mask parameter can be omitted.
unsetf(mask) Delete the mask format based on the current format.

The optional values of fmtfl and mask are:

Sign effect
ios::boolapha Output true and false as strings
ios::left The output data is aligned to the left within the wide range of this field
ios::right The output data is aligned to the right within the wide range of this field
ios::internal The sign bit of the value is aligned to the left within the field width, the value is aligned to the right, and the middle is filled with filling characters
ios::dec Set the cardinality of an integer to 10
ios::oct Set integer cardinality to 8
ios::hex Set the cardinality of an integer to 16
ios::showbase Force the cardinality of the output integer (octal number starts with 0, hexadecimal number starts with 0x)
ios::showpoint Force the output of the dot and mantissa of floating-point numbers 0
ios::uppercase In scientific notation format E and in hexadecimal output letters are in uppercase
ios::showpos Display “+” sign for positive number
ios::scientific Floating point number scientific notation format output
ios::fixed Floating point number fixed point format (decimal form) output
ios::unitbuf Refresh all streams after each output

Here are some examples:

【flags(fmtfl)】Replace the current format status with fmtfl

bool a = true;
cout << a << endl;

Bool type is essentially an integer. When a=true, the print display is 1. When a=false, the print display is 0.

If you want to print and display as: true or false, you need to format the output.

bool a = true;
cout.flags(ios::boolalpha);
cout << a << endl;

The output format passed in by the flags function of cout object is ios:: boolalpha (output true and false as strings).

【precision(n)】Set the precision of the output floating-point number to n

float a = 1.1f;
double b = a / 3;
cout << b << endl;

The print result of the above code is:

0.366667

If you want to keep only two decimal places, you need to format the output results:

float a = 1.1f;
double b = a / 3;
cout.precision(2);
cout << b << endl;

The output is:

0.37

【width(w)】Specifies that the output width is w characters

cout.width(20);
cout << "zhangsan" << endl;

The output of the above code is:

        zhangsan

The output width is 20, and the default alignment is right.

The alignment methods are divided into left alignment and right alignment. You can set the flag to ensure its alignment:

Align left:

cout.flags(ios::left);

Align right:

cout.flags(ios::right);

[output of positive sign]

For the output of negative and positive numbers, the output of negative numbers is-The output of positive numbers does not have+If you want to output the symbol of a positive number, you need to format the output of a positive number:

cout.flags(ios::showpos);
cout << 100 << endl;

The output is:

+100

combinationios::internalUse to align the sign bit of a numeric value to the left within the field width, align the numeric value to the right, and fill the middle with a filling character:

cout.width(20);
cout.flags(ios::showpos | ios::internal);
cout << 100 << endl;

The output is:

+                100

【fill(c)】When the output width is specified, it is filled with the character c when the output width is insufficient (filled with spaces by default)

cout.width(20);
cout << "zhangsan" << endl;

The output of the above code is:

        zhangsan

By default, the front of the output result is filled with spaces, which is equivalent to:

cout.width(20);
cout.fill();
cout << "zhangsan" << endl;

However, if you want to fill the space on the left with other characters, you need to call the fill function to fill the characters:

cout.width(20);
cout.fill('#');
cout << "zhangsan" << endl;

The output is:

############zhangsan

[binary output]

The output formats of cout related hexadecimals are:

Ios:: Dec: sets the cardinality of an integer to 10
Ios:: OCT: sets the cardinality of an integer to 8
Ios:: hex: sets the cardinality of an integer to 16

The codes are as follows:

int a = 177;

cout. flags(ios::dec); //  Decimal output
cout << a << endl;

cout. flags(ios::oct); //  Octal output
cout << a << endl;

cout. flags(ios::hex); //  Hex output
cout << a << endl;

The output result of the above code is:

177
261
b1

Among them, the output results of octal and hexadecimal are strange. They are not very standardized (octal should start with 0, and hexadecimal should start with 0x). The output format is:ios::showbaseYou can make the display of hexadecimal numbers more standard. The code is as follows:

int a = 177;

cout. flags(ios::dec); //  Decimal output
cout << a << endl;

cout. flags(ios::oct | ios::showbase); //  Octal output
cout << a << endl;

cout. flags(ios::hex | ios::showbase); //  Hex output
cout << a << endl;

The output is:

177
0261
0xb1

【unsetf(mask)】Delete the mask format based on the current format

cout.width(20);
cout.flags(ios::showpos | ios::internal);
cout << 100 << endl;

The output of the above code is:

+                100

Ios:: showpos: sign output for positive numbers
Ios:: Internal: indicates left alignment of symbols and right alignment of values

If you want to remove ios:: internal, you need to call unsetf function:

cout.width(20);
cout.flags(ios::showpos | ios::internal);
cout.unsetf(ios::internal);
cout << 100 << endl;

The output result is:

                +100

【setf(fmtfl, mask)】Add fmtfl format to the current format and delete mask format. The mask parameter can be omitted

If you want to add an output format, you can use the setf function:

cout.width(20);
cout.flags(ios::showpos);
cout.setf(ios::internal);
cout << 100 << endl;

The above code setf has only one parameter. It can take two parameters, but the current test results are problematic.

[force output of dot and mantissa 0 of floating-point number]

Use output formatios::showpointYou can force the output of the dot and mantissa 0 of a floating-point number:

float a = 1;
cout.flags(ios::showpoint);
cout << a << endl;

The output is:

1.00000

[output in scientific counting format]

Use output format:ios::scientificFloating point numbers can be output in scientific notation format. The code is as follows:

float a = 1.11f;
cout.flags(ios::scientific);
cout << a << endl;

The output is:

1.110000e+00

If you want to restore to decimal output, you can re execute the decimal output format:ios::fixed, code as follows:

float a = 1.11f;
cout.flags(ios::scientific);
cout << a << endl;
cout.flags(ios::fixed);
cout << a << endl;

The output format is:

1.110000e+00
1.110000

[output in capital format]

Use output format:ios::uppercaseOutput in uppercase format can be realized, but it is only applicable to scientific counting method and hexadecimal. The demonstration code is as follows:

float a = 1.11f;
cout. flags(ios::scientific | ios::uppercase); //  Scientific counting small letter to capital letter
cout << a << endl;

int b = 177;
cout. flags(ios::hex | ios::showbase | ios::uppercase); //  Hexadecimal lowercase to uppercase
cout << b << endl;

The output is:

1.110000E+00
0XB1
(6) Format output using flow manipulators

Some common format controllers defined in the <iomanip> header file can be used to format output:

Flow manipulation operator effect Commonly used
Dec (default) Output integer in decimal form Commonly used
hex Output integer in hexadecimal form Commonly used
oct Output integer in octal form Commonly used
fixed Output floating point numbers as normal decimals Commonly used
scientific Output floating point numbers as scientific counting Commonly used
left Align left, which adds padding characters to the right when the width is insufficient Commonly used
Right (default) Right aligned, which adds padding characters to the left when the width is insufficient Commonly used
setbase(b) Set the base value when outputting integers, b=8, 10 or 16 Commonly used
setw(w) Specifies that the output width is w characters, or that w characters are read when a string is entered. Note that this function only affects the next cout output. Commonly used
setfill(c) When the output width is specified, it is filled with the character c when the output width is insufficient (filled with spaces by default) Commonly used
setprecision(n) Set the precision of the output floating-point number to n.
In the case of non fixed and non scientific output, n is the largest number of significant digits. If the number of significant digits exceeds n, the decimal part will be rounded off, or it will be automatically output by scientific counting method and a total of N significant digits will be retained.
When using fixed mode and scientific mode for output, n is the number of digits that should be reserved after the decimal point.
Commonly used
setiosflags(mask) In the current format status, the mask format is added. All values in Table 2 can be selected for the mask parameter. Commonly used
resetiosflags(mask) In the current format status, delete the mask format. All values in Table 2 can be selected for the mask parameter. Commonly used
boolapha Output true and false as strings Not commonly used
Noboolalpha (default) Output true and false as 0 and 1 Not commonly used
showbase Outputs a prefix that represents the base of a numeric value Not commonly used
Noshowbase (default) Do not output base numbers that represent numeric values Prefix of Not commonly used
showpoint Always output decimal point Not commonly used
Noshowpoint (default) Display decimal point only if decimal part exists Not commonly used
showpos Display in non negative values+ Not commonly used
Noshowpos (default) Do not display in non negative values+ Not commonly used
uppercase A~e are used in hexadecimal numbers. If the prefix is output, the prefix is output as 0x, and the scientific counting method is output as E Not commonly used
Nouppercase (default) Use a~e in hexadecimal numbers. If the prefix is output, the prefix outputs 0x, and the scientific counting method outputs E. Not commonly used
internal The sign (plus or minus) of the value is aligned to the left within the specified width, the value is aligned to the right, and the middle is filled with fill characters. Not commonly used

Its usage can be illustrated by example:

int a = 177;
cout << hex << a << endl; //  Hex format output
cout << setbase(8) << a << endl; //  Octal format output

float b = 1.11f;
cout << scientific << b << endl; //  Scientific counting format output

float c = 1.110000e+00;
cout << fixed << c << endl; //  Decimal format output

string e = "zhangsan";
cout << setw(20) << left << setfill('C') << e << endl; //  Width 20, left aligned, filled with character c

cout << setprecision(2) << 1.1111 << endl; //  Set the precision of floating-point numbers, keeping 2 decimal places

float f = 1.11f;
cout << setiosflags(ios::scientific) << f << endl; //  In the current format status, append mask format
cout << resetiosflags(ios::scientific) << f << endl; //  In the current format status, delete the mask format

The output is:

b1
261
1.110000e+00
1.110000
zhangsanCCCCCCCCCCCC
1.11
0x1.1c28f60000000p+0
1.11
(7) Input / output redirection

By default, CIN can only receive data input from the keyboard, and cout can only output data to the screen. However, through redirection, CIN can use the specified file as the input source, that is, it can receive the data already prepared in the file. Similarly, cout can write the data originally to be output to the screen to the specified file.

In c++, there are three common ways to implement redirection:

(1) The freopen() function implements redirection

    FILE* file = new FILE();
    string lineStr;

    freopen_ s(&file, "in.txt", "r", stdin); //  Redirect standard input stream to in Txt file
    freopen_ s(&file, "out.txt", "w", stdout); //  Redirect standard output to out Txt file
    while (cin >> lineStr) 
    {
        cout << lineStr << endl;
    }
    fclose(stdout);
    fclose(stdin);

At this point, CIN and cout are redirected to the input and output of the file, so how to restore to the console output?

Restore to console output:
    freopen_s(&file, "CON", "w", stdout); 
Restore to console input (visual invalid):
    freopen_s(&file, "CON", "r", stdin);

(2) Rdbuf() function to implement redirection

    ifstream fin("in.txt"); // Open in Txt file, waiting to be read
    ofstream fout("out.txt"); //  Open out Txt file, waiting to be written
    streambuf* oldcin;
    streambuf* oldcout;
    string linStr;
    oldcin = cin. rdbuf(fin.rdbuf()); //  Redirect with rdbuf()
    oldcout = cout. rdbuf(fout.rdbuf()); // Redirect with rdbuf()
    While (CIN > > linstr) /// from input Txt file is read in and written out txt
    {
        cout << linStr << endl;
    }
    cin. rdbuf(oldcin); //  Restore keyboard input
    cout. rdbuf(oldcout); // Restore screen output

    fin.close();
    fout.close();

(3) Redirection via console

CMD open the console and enter: xxx Exe, the executable file "xxx.exe" of the application can run the code directly, but it cannot redirect CIN and cout;
If you enter: xxx exe <in. txt >out. Txt, you can redirect;

<in. Txt: redirect CIN from console input to file (in.txt) input. Ensure that the file in. exists in the current directory txt;
>out. Txt: redirect cout from console output to file (out.txt) output.

Edit code:

string lineStr;
while(cin >> lineStr)
    cout << lineStr << endl;

Enter: xxx exe <in. txt >out. txt 

At this time, it is found that in Txt has been written to out Txt file.
(8) How to ignore input specified characters
int n;
cin.ignore();
cin >> n;
cout << n;

The ignore function of CIN can ignore the input character. In the above code, ignore() ignores a character. If you enter:

12345

Then the output result is:

2345

The ignore function can also contain a formal parameter

istream & ignore(int n =1);

Indicates skipping a few characters.

The ignore function can also contain two formal parameters:

istream & ignore(int n =1, int delim = EOF);

This function is used to skip n characters in the input stream, or to skip delim and all characters before delim. Whichever condition is satisfied first will be executed.
Both parameters have default values, so cin Ignore () is equivalent to cin Ignore (1, EOF), that is, skip one character.

Example codes for two parameters:

int n;
cin.ignore(5, '1');
cin >> n;
cout << n;

The input and output results are:

ABC123
23
(9) View next character in input stream

The peek() function of CIN can view the next character in the input stream.

[end of this chapter…]