Operation of IO stream and file

Posted by vangelis on Wed, 29 Dec 2021 15:59:55 +0100

1. Input / output concept

Standard input and output, referred to as standard I/O, that is, keyboard input data and input data from the screen
File input / output, referred to as file I/O, inputs data from disk files and outputs the results to disk files.

2. Input / output stream

Stream: data flows from one place to another like water.
C + + will open up a place called buffer for each data in memory to store stream data.
For example, cout and the output operator "< <" output data to the display. In fact, first transfer the data to the buffer for fetching until the buffer is full or the end or program ends. At this time, transfer the data from the buffer to the display for display.

Storage sequence of output data: cout < < buffer   display
When inputting data, first input the data to the keyboard buffer through the keyboard. When pressing enter, it is transmitted from the keyboard buffer to the input buffer to form a cin stream, and then use "> >" to transfer the data from the input buffer to the associated variables in the program

Input data storage order: keyboard buffer   input buffer   program associated variables through input stream  

2.1. Common stream classes in I / O Libraries

ios: abstract base class. ios derives class istream and class ostream
istream: an input stream class that supports input operations
ostream: output stream class, which supports output operations
iostream: input / output stream class, derived from istreamhe and ostream, which supports input / output operations
ifstream: the input file stream class, derived from istream, supports file input operations
ofstream: output file stream class, derived from class ostream, which supports file output operations
Fsstream: output / input file stream class, derived from iostream class, which supports file input / output operations
As shown in the figure:

2.2. Header file of common stream classes in io Library

iostream(iostream.h): including ios, istream, ostream and iostream.
Fsstream (fsstream. H): including class i fstream, class ofstream and class fsstream
iomanip(iomanip.h): the input flow controller should be included in this file

3. Standard output stream object

3.1.cout

cout is the English abbreviation of consle pouput, which represents the output of the terminal display. cout is the object of the output stream class ostream. cout first transmits the data to the buffer, and then from the buffer to the terminal display.
Example:

cout << "I" << "like to study" << "C++" << endl;

During execution, "I", "love learning", "C + +" and endl are successively added to the buffer. When the buffer is full or encounters end or the program ends, the data from the buffer is transmitted to the display for display.

3.2 format output

When outputting data before, no output format is specified. The system outputs data according to the default format of the data type, but sometimes you want to output data according to the specified format, for example, you want to keep two decimal places in the output.
The format state of the output is the enumeration value defined in the ios class.
If the format status is expressed, the scope operator of ios class needs to be added in front of it:
                   common output format status

Output format statusfunctionOutput format statusfunction
ios::leftAlign output data leftios::scientificFloating point number scientific counting format output
ios::rightAlign output data rightios::fixedFloating point number fixed-point format (decimal form) output

The output flow controller is defined in the header file iomanip(iomanip.h). The output flow controller is shown in the following table:

                     common output flow control characters

Input flow controllerfunction
setprecision(n)Set the real precision to n bits. When output in general decimal form, n represents significant digits. When outputting in fixed-point format and scientific notation format, N decimal places will work for each subsequent output item
setw(n)The width of the position output item is n bits, which only works on the first output item after it
setfill(ch)Set the padding character ch to work for each subsequent output item
Setiosflags (output format status)Set the output format status. The output format status is given in parentheses
Resetionsflags (output format status)Terminates the set output format state

Code example:

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
	cout << setiosflags(ios::left)             //Set left alignment
		<< setw(10)                            //Set width
		<< setfill('*')                        //Set filler
		<< "Align left" << endl                    //Output content
		<< resetiosflags(ios::left);           //Turn off left alignment

	cout << setiosflags(ios::right)            //Set right alignment
		<< setw(10)                            //Set width
		<< setfill('*')                        //Set filler
		<< "Right align" << endl                    //Output content
		<< resetiosflags(ios::right);          //Turn off right alignment

	cout << setiosflags(ios::scientific)       //Set scientific counting method
		<< setprecision(8)                     //Output 8 decimal places
		<< 7.0/3 << endl                       //Output content
		<< resetiosflags(ios::scientific);     //Turn off scientific counting mode

	cout << setiosflags(ios::fixed)            //Set floating point mode
		<< setprecision(8)                     //Output 8 decimal places
		<< 7.0 / 3 << endl                     //Output content
		<< resetiosflags(ios::fixed);          //Turn off floating point mode

	cout << setprecision(8)                     //Set to output in general decimal form, and output 8 as a number
		<< 7.0 / 3 << endl;                     //Output content
	system("pause");
	return 0;
}

Operation results:

Among them, setw(10) plays a role in the following first output item. If the following output width is also 10, it needs to be reset.
setfill('*') setting padding works for all subsequent outputs
setprecision(8) setting precision also plays a role in all subsequent outputs

3.3 control output format using output class member functions

In addition to using the controller to control the output format, it can also control the output format by calling the member function of the stream object cout, which is used to control the common member function of the output format

                      member functions of common output stream control formats

Member functionEquivalent output stream controllerfunction
precision(n)setprecision(n)Set the real precision to n bits. When output in general decimal form, n represents significant digits. When outputting in fixed-point format and scientific notation format, N decimal places will work for each subsequent output item
width(n)setw(n)The width of the position output item is n bits, which only works on the first output item after it
fill(ch)setfill(ch)Set the padding character ch to work for each subsequent output item
Setf (output format status)Setiosflags (output format status)Set the output format status. The output format status is given in parentheses
Unsetf (output format status)Resetionsflags (output format status)Terminates the set output format state

Code example:

#include <iostream>
using namespace std;
int main()
{
	cout.setf(ios::left);           //Set left alignment
	cout.width(10);                 //Set the width to 10
	cout.fill('*');                 //Set the padding character to '*'
	cout << "Align left" << endl;       //Output content
	cout.unsetf(ios::left);         //End left alignment

	cout.setf(ios::right);          //Set right alignment
	cout.width(10);                 //Set the width to 10
	cout.fill('*');                 //Set the padding character to '*'
	cout << "Right align" << endl;       //Output content
	cout.unsetf(ios::right);        //End right alignment

	cout.setf(ios::scientific);     //Set floating point numbers to be output in scientific counting method
	cout.precision(8);              //Set to output in scientific counting method, with 8 decimal places reserved
	cout << 7.0 / 3 << endl;        //Output content
	cout.unsetf(ios::scientific);   //Ways to terminate science and Technology Law

	cout.setf(ios::fixed);          //Set floating point number to output in fixed-point format (decimal form)
	cout.precision(8);              //Output 8 significant digits
	cout << 7.0 / 3 << endl;        //Output content
	cout.unsetf(ios::fixed);        //Terminate floating point format output

	cout.precision(8);              //Set to output 8 significant digits when output in the form of general decimal digits
	cout << 7.0 / 3 << endl;        //Output content
	system("pause");
	return 0;
}

Operation results:

4. Common input / output stream member functions

4.1 output stream member function put()

For the output of a single character, in addition to the output operator "< <", it can also be implemented with the output stream member function put()
Code example:

#include <iostream>
#include <cstring>
using namespace std;

int main()
{
	char ch[30];
	int i;
	cin >> ch;
	for (i = 0; i < strlen(ch); i++)
		cout.put(ch[i]);
	cout << "\n";
	system("pause");
	return 0;
}

Operation result 1:

Operation result 2:

Through the test, the function ends when it encounters a space. It cannot print a space. When it encounters a space, it ends the subsequent output

4.2 input stream member function get()

The member function get() is used to input a single character, as follows:
cin.get()
Code example:

#include <iostream>
using namespace std;
int main()
{
	char ch;
	cout << "Please enter a line of characters:" << endl;
	ch = cin.get();
	while (ch != '\n')
	{
		cout.put(ch);
		ch = cin.get();
	}
	cout << '\n';
	system("pause");
	return 0;
}

Operation results:

4.3 input stream member function getline()

The function of the getline() member function is to enter a line of characters from the input stream object
Format:
  input stream object Getline (character pointer, number of characters)
Example:

#include <iostream>
using namespace std;
int main()
{
	char ch[20];
	cin.getline(ch, 5);
	cout << ch << endl;
	system("pause");
	return 0;
}

Operation results:

The number of characters set here is 5, including abcd '\ 0'
But actually getline has three parameters, and the third parameter is the terminator
Example:

#include <iostream>
using namespace std;
int main()
{
	char ch[20];
	cin.getline(ch, 10, '*');
	cout << ch << endl;
	system("pause");
	return 0;
}

Operation results:

At this time, the end character set is the word symbol, and it ends when it meets the sign

4.4 input stream member functions eof(), peek(), putback()

eof() function
Format:
Input stream object eof()
Function:
  used to detect whether the end of the file is reached. If it is reached, it returns true; otherwise, it returns false.

peek() function
Format:
Input stream object peek()
Function:
  the character used to view the input stream of the current object, but the current position of the input stream object remains unchanged

putback() function
Format:
Input stream object putback()
Function:
  used to insert a character into the current input stream object position.
Example:

#include <iostream>
using namespace std;
int main()
{
    char ch1[20];
    char ch2;
    cin >> ch1;
    // cin.getline(ch1, 20, '*');
    cout << ch1 << endl;
    ch2 = cin.peek();    //Returns the next character in the input stream
    cout << ch2 << endl;  //View characters in the input stream
    cin.putback(ch1[0]);   //Inserts the first element of the array into the input stream
    ch2 = cin.peek();      //View the data of the current input stream
    cout << ch2;
    system("pause");
    return 0;
}

Operation results:

Input: qianfeng enter ('\ n') now all qianfeng and enter ('\ n') are in the input buffer, and then press enter
Then qianfeng is transferred to the variables associated with the code. Here is a ch1 array, and the one left in the buffer is' \ n '
At this time, I use the peek() function to monitor the data in the buffer and return it to ch2. At this time, the output statement is cout < < ch2 < < endl;
ch2 gets a newline through the buffer, then outputs endl newline, and then through putback(ch1[0]) the statement is
The first element of the ch1 string is inserted into the buffer and monitored at this time. The result is q, because the string is qianfeng and the first element is q

Output results:
qianfeng
qianfeng
enter
enter
q

5. File operation and file flow

Classification of documents: ordinary documents and equipment documents.
Normal file: a file stored on disk
Device files: external devices (mouse, keyboard)

File coding is divided into ASCII file and binary file
Store ASCII code
  for example: 5 6 8 0 storage form
0011 0101   0011 0110   0011 1100   0011 0000
  5         6         8         0

Binary files are stored in binary encoding.
For example, number: 5 6 8 0 storage form
00000000   00000000      00010110   00101110

File stream is actually a data stream with external storage files as input and output objects.
Output file: flow from memory to file
Input file: flow from file to memory

ifstream: derived from istream class, used to support file input operations.
ofstream: derived from the ostream class and used to support file output operations.
Fsstream: derived from iostream class and used to support file input and output operations.

Example definition file object:
ofstream outFile; // Defines the output file stream object outfile
ifstream intFile; // Defines the input file stream object IntFile
fstream File; // Define the input / output file stream object file

5.1 opening and closing of files

                 common file operation methods

File operation modefunction
ios::inOpen the file in output mode. If the file does not exist, an error will occur. Otherwise, it will be opened successfully. It is the default opening mode of file stream class ifstream. After opening, the current position of the file is at the beginning of the file
ios::outOpen the file in the output mode. If the file does not exist, a new file will be created, otherwise the file will be emptied. It is the default opening mode of the file stream class ofstream. After opening, the current position of the file is at the beginning of the file
ios::appOpen by appending. If the file already exists, the original content will not be cleared, otherwise the compiler will report an error, and the current position of the file after opening is at the end of the file
ios::binaryOpen the file in binary mode. If this mode is not specified, it defaults to ASCII mode. The opening mode is

There is a file pointer inside each open file stream object, which is used to point to the current operation location. Each read-write operation starts from the file pointer pointing to the current location. When a byte is read, the pointer moves back one byte.
When the file pointer moves to the end, the EOF file terminator will be encountered. At this time, the value of the object's member function eof() is true, indicating the end of the file.
  input and output modes can be combined with bit or operator "|"
ios::in | ios::out / / open a text file in input / output mode
ios::app | ios::binary / / open a binary file by appending

There are two ways to open a file:
File stream object Ope (file name, file operation mode)
for example

ofstream outFile;
outFile.open("1.txt", ios::out);

or

ofstream outFile("1.txt", ios::out);

If the file fails to open, the file stream member function fail() returns true, otherwise it returns false

ofstream outFile("1.txt", ios::out);
if (outFile.fail())
{
    cout << "File open failed!" << endl;
}

5.2 close file

When the operation on the open external storage file is completed, the file should be closed. Close the file using the member function close().
The format is as follows:
  file stream object close()
For example:

outFile.close();

Closing the file will release the relationship between the external file and the file stream object, so the file can no longer be operated through the file stream object.

5.3 document operation

5.3. 1 example 1

Will contain 8 integers, store these data into a text file, and then read the data from this file and display it on the screen.
Code example:

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
	int a[] = { 1,2,3,8,2,5,6,7 };
	int n = 8;
	int k;                          //Stores elements read from a file
	fstream f;                      //File input / output stream object f
	f.open("1.txt", ios::out);      //Open file in output mode 1 Txt, if 1 Txt file does not exist, a new 1.txt file will be created automatically Txt file
	if (f.fail())                   //Judge whether the opening is successful. If the opening fails, return true. If the opening succeeds, return false
	{
		cout << "Open failed!" << endl;
		exit(1);
	}
	for (int i = 0; i < 8; i++)
		f << a[i] << " ";           //Output to file is 1 Txt
	f.close();                      //Close file

	f.open("1.txt", ios::in);       //Open as input
	if (f.fail())                   //Judge whether the opening is successful. If the opening fails, return true. If the opening succeeds, return false
	{
		cout << "Open failed!" << endl;
		exit(1);
	}
	while (!f.eof())                 //Judge whether to reach the end of the file, return true or not, and return false
	{
		f >> k;                      //For each input to variable k and output, the file pointer moves back one byte
		cout << k << " ";
	}
	cout << '\n';
	f.close();
	system("pause");
	return 0;
}

Operation results:

In the current folder, a file named "1.txt" is generated automatically
The contents written in this folder are also the values of array elements.
But the number 7 was found on the console
This is because each time a number is entered into the file, it takes a space
In this way, when the file pointer points to position 7, then input 7 to k, and then output 7 and a space. At this time, the file pointer moves one bit to reach the space position behind the number 7 in the file. At this time, the while judgment is true, and then input the space to k, but the input is not successful. k is still 7 at this time. At this time, execute the output and output a 7 and a space, Finally, the results of two 7 are output.

5.3. 2 example 2

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
	char ch;
	int letters = 0;                             //Number of traversal file letters
	ofstream outFile("10.txt", ios::out);       //Open file as output
	if (outFile.fail())                         //Judge whether it is opened successfully
	{
		cout << "Open failed!" << endl;
		exit(1);
	}
	ch = cin.get();
	while (ch != '\n')
	{
		outFile.put(ch);
		ch = cin.get();
	}
	outFile.close();                            //Close file

	ifstream inFile("10.txt", ios::in);         //Open file as input
	if (inFile.fail())                         //Judge whether it is opened successfully
	{
		cout << "Open failed!" << endl;
		exit(1);
	}
	while (!inFile.eof())       //It is judged that it is not at the end of the file
	{
		ch = inFile.get();
		if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z')
		{
			cout.put(ch);
			letters++;
		}
	}
	cout << endl << "Common English letters" << letters << "individual" << endl;
	system("pause");
	return 0;
}

Operation results:

The current folder is automatically generated

5.3. 3. Garbled code in file reading and writing operation

If I am to an existing 1 Txt file to read the Chinese of the file. The result is indeed garbled.
Because the codes are different.
Press win+R to enter cmd


Then back click the top spline box and select the attribute

The code is GBK
The code of Notepad is UTF-8

If a 1 Txt notepad file already exists in advance. At this time, read the data of the file directly. If the data in the file is Chinese, it may be garbled
So the solution:
  write to the file first, and then read to the file. My understanding is that only write is performed first, but if the file does not exist, it will be created automatically txt file, and then the read operation can be performed. At this time, the read file format is the same.
Note: to execute the write operation, you must write in the data, which is considered successful. If you just want the code to generate one txt file is no good, sir txt file, and then write things in
If txt file already exists in advance. An example of reading first is as follows:
Read operation (failed) example:

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
	char s[100];      //Read from file data into s array
	char name[100];   //file name
	fstream file;     //Input / output stream object

	cout << "Please enter the file name to read:";
	cin.getline(name, 100);
	
	file.open(name, ios::in);   //Open an existing file by reading
	if (file.fail())
	{
		cout << "Open failed" << endl;
		exit(1);
	}
	file.getline(s, 100);   //Read the contents of the file into the character array s
	file.close();           //Close file
	cout << s << endl;      //Print what you read
	system("pause");
	return 0;
}

Operation results:

I created a new 4 Txt file, which reads: "I love learning C + +"

Because it's a 4. 0 I created manually Txt file, prepared file in advance, and then I write a read 4 Txt file. It is found that part of the read code is garbled, but C + + reads it later. Chinese is garbled. One Chinese occupies 2 bytes and one letter occupies 1 byte. Different coding methods lead to garbled Chinese.
At this time, if I execute the write operation first and then the read operation, see if there are different results:
Example:

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
	char s[100];      //Read from file data into s array
	char name[100];   //file name
	fstream file;  //Input stream object

	cout << "Please enter a file name:";
	cin.getline(name, 100);
	file.open(name, ios::out);  //Open file in write mode
	if (file.fail())
	{
		cout << "Open failed" << endl;
		exit(1);
	}
	file << "I love learning. C++";    //Write the data in
	file.close();            //Close file
	
	//file.open(name, ios::in);   // Open file in read mode
	//if (file.fail())
	//{
	//	Cout < < open failed < < endl;
	//	exit(1);
	//}
	//file.getline(s, 100);
	//file.close();           // Close file
	//cout << s << endl;
	system("pause");
	return 0;
}

Operation results:

At this point, a 10. 0 is automatically generated TXT text file, and 10 TXT text file has something written in, which is considered successful.


At this time, the "I love learning C + +" is successfully written, which is the completion of the write operation.
Next, comment out the part of the write operation and perform the read operation.

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
	char s[100];      //Read from file data into s array
	char name[100];   //file name
	fstream file;  //Input stream object

	cout << "Please enter a file name:";
	cin.getline(name, 100);
	//file.open(name, ios::out);  // Open file in write mode
	//if (file.fail())
	//{
	//	Cout < < open failed < < endl;
	//	exit(1);
	//}
	//File < < I love learning C + +;
	//file.close();            // Close file
	
	file.open(name, ios::in);   //Open file in read mode
	if (file.fail())
	{
		cout << "Open failed" << endl;
		exit(1);
	}
	file.getline(s, 100);
	file.close();           //Close file
	cout << s << endl;
	system("pause");
	return 0;
}

Operation results:

I read it in Chinese, but if it's 10 Change the Chinese in TXT file to the Chinese I want, and then perform the reading operation.

At this point 10 The Chinese in txt is changed to: "I like learning, learning makes me happy". At this time, continue to read the file.
Operation results:

Read successfully.

Summary: if you want to read Chinese, first perform the write operation. When performing the write operation, you should write Chinese to txt text file is considered successful, and then the read operation can be performed in the file. At this time, the The Chinese in txt file can be changed into anything you want to read.
But if there is one txt text file already exists (created manually) and contains Chinese. At this time, if you want to read the existing text file directly txt file, Chinese can only read garbled code, unless the encoding format of the text file is changed:

Operation steps

Click file, and then click Save as

The code is changed to ANSI format, which is the same as the previous GBK format.
But there is a problem with Notepad. Even if the ANSI format is changed, it defaults to UTF-8 format.

5.3. 4. Binary file operation functions ------ read() and write()

The read() function reads the data of the file into the variables associated with the code
The write() function writes the data to the specified file

Two function declaration formats:
File stream object Read (character pointer buffer, length len);
File stream object Write (character pointer buffer, length len);
Character pointer buffer refers to a storage space in memory, and len refers to the number of bytes read and written
Code example:

#include <iostream>
#include <fstream>
using namespace std;

int main()
{
	int a[] = { 1,2,3,4,5,6 }, b;


	fstream file;                                  //Input / output stream object
	file.open("10.txt", ios::out | ios::binary);    //Binary write mode on 1 Txt file
	if (file.fail())                               //File failure returns true
	{
		cout << "File creation failed!" << endl;
		exit(1);
	}
	for (int i = 0; i < 6; i++)
		file.write((char *)&a[i], sizeof(int));    //Each element written is an int byte size
	file.close();                                  //Close file




	file.open("10.txt", ios::in | ios::binary);                  //Binary read mode on 1 Txt file
	if (file.fail())                               //File failure returns true
	{
		cout << "File creation failed!" << endl;
		exit(1);
	}
	file.read((char *)&b, sizeof(int));             //Read an int byte of data into b
	while (!file.eof())                              //Judge whether the file reaches the end. If it reaches the end, it returns true, otherwise it returns false
	{
		cout << b << " " ;
		file.read((char*)&b, sizeof(int));             //Read an int byte of data into b
	}
	cout << endl;
	file.close();
	system("pause");
	return 0;
}

Operation results:


But found 10 TXT text files are garbled because read and write are in binary form.
among

for (int i = 0; i < 6; i++)
		file.write((char *)&a[i], sizeof(int));    //Each element written is an int byte size

These two lines of code can be replaced by

file.write((char *)&a[0], sizeof(int));    //Each element written is an int byte size

Topics: C++