C + + : file operation


File operation is an indispensable part of program development. Any software that needs data storage needs file operation. File operations include opening, reading and writing files.

(1) Stream class library in C + +

C + + language defines special class libraries for standard input and output of different types of data. The class libraries mainly include IOS, istream, ostream, ifstream, istrstream, iostream, ostrream, OFSTREAM, fstream and strstream. The inheritance relationship between them is as follows:

C + + : file operation


The basic names of these stream classes are as follows:

IOS: basic class
Istream: input stream class
Ostream: output stream class
Ifstream: input file stream class
Istrstream: input string stream class
Iostream: input / output stream class
Ostrstream: output string stream class
OFSTREAM: output file stream
Fsstream: file stream
Strstream: character stream

These stream classes are defined in the I / O standard library < iostream >, < fsstream >, < strstream >.

(2) Use of string stream
char buf[] = "12345678";
int a, b;
istrstream s1(buf);
s1 >> a;
istrstream s2(buf, 3);
s2 >> b;
cout << a + b << endl;

ostrstream   s3;
s3 << "123" << ends;
cout << s3.str() << endl;
delete s3.str();

The running result of the above code is:


Use istrstream to convert a string to an integer, a = 12345678, B = 123, a + B = 12345801.
Use ostrstream to store 123 in the cache and output it finally.

(3) Open file

Only when the file stream is associated with the file on the disk can the file be operated. This associated process is called opening the file.

There are two ways to open a file:

(1) When creating a file stream, use the constructor to open the file. The example code is as follows:

     ofstream outfile("test.txt", ios::out);
     ifstream infile("test.txt", ios::in);
     fstream file("test.txt", ios::in|ios::out);

OFSTREAM is a file stream class, which can also be ifstream or fsstream;
Outfile is the name of the file stream object;
There are two parameters in the constructor. The first parameter is: file name path (absolute path or relative path);
The second parameter of the constructor is the opening method, which is defined in the IOS class, including input method, output method, addition method, etc., as follows:

IOS:: in: open the file in the input mode. The file can only be read and cannot be overwritten;
IOS:: out: open the file in output mode, which can only be rewritten and cannot be read;
IOS:: app: open the file by appending. After opening, the file pointer is at the end of the file and can be rewritten;
IOS:: ate: open an existing file. The file pointer points to the end of the file and can be rewritten;
IOS:: binary: open the file in binary mode;
IOS:: TRUNC: open the file for writing. If the file already exists, clear the data in the file;
IOS:: nocreate: open the existing file. If the file does not exist, the opening fails and the file will not be created;
IOS:: norreplace: create a new file. If the file already exists, the opening fails and will not be overwritten;
IOS:: in|ios:: out: open the file in read-write mode and make it readable and writable;
IOS:: in|ios:: binary: open the file in binary mode for reading;

(2) Use the open function to open the disk file. The code example is as follows:

    ifstream infile;
    infile.open("text.txt", ios::in);
    ofstream outfile;
    outfile.open("text.txt", ios::out);
    fstream file;
    file.open("text.txt", ios::in|ios::in);

In addition, there is a third parameter when opening the file:

    ifstream infile("test.txt", ios::in, 0);

    ifstream infile;
    infile.open("text.txt", ios::in, 0);

The third parameter is the file access method. The values are as follows:

0: normal file
1: Read only file
2: Implied file
3: System file
(4) File reading and writing

When operating on files, it must be inseparable from reading and writing files. When using the program to view the file content, you must first read the file, and when you want to modify the file content, you need to write data to the file.

The file input stream is ifstream, and the file output stream is OFSTREAM. They have some member functions:

Attach: establish a connection between an open file and a stream;
Close: close the file after refreshing the unsaved data;
Flush: refresh the stream;
Open: open a file and connect it to the stream;
Put: write a byte into the stream;
Rdbuf: returns the filebuf object connected to the stream;
Seekp: set the pointer position of stream file;
Setmode: set the stream to binary or text mode;
Tellp: get the pointer position of stream file;
Write: write a group of bytes into the stream;

The file stream object ftream is a combination of ifstream and OFSTREAM. Its member functions include:

Get: read a character from the file;
Getline (STR, N, '\ n'): the characters read from the file are stored in the string until n-1 characters are read or "\ n" is encountered;
Peek: find the next character, but do not take it out of the file;
Put: write a character to the file;
Putback: returns a character to the input stream, but does not save it;
EOF: returns true if the read exceeds EOF;
Ignore (n): skip n characters. When the parameter is empty, it means skip the next character;

The demonstration code of file reading and writing operation is as follows:

char buf[128];
ofstream ofile("test.txt");
for (int i = 0; i < 5; i++)
    memset(buf, 0, 128); //  Initialize array
    cin >> buf;   //  Enter data in the console
    ofile << buf; //  Save the input data to a file
ofile. close(); //  Close flow

ifstream ifile("test.txt");
while (!ifile.eof())
    char ch;
    ifile. get(ch); //  read file
    If (! Ifile. Eof()) // judge whether it is the end
        cout << ch;
cout << endl;
ifile. close(); //  Close flow

The logic of the above code is:

(1) File output stream ofile and file test Txt Association;
(2) Output 5 data on the console;
(3) Storing data in files;
(4) File input stream ifile and file test Txt Association;
(5) Read the file and print the data to the console;

Here is another example of file copying:

ifstream infile;
ofstream outfile;
char name[20];
char c;
infile. open("test.txt"); //  Open file
If (! Infile) // judge whether the file exists
    Cout < < "the original file does not exist!"<< endl;

outfile. open("test_copy.txt"); //  Open the file and create it if it does not exist

while (infile.get(c)) 
    outfile << c;
(5) File error and status

Various errors may occur during the operation of I / O streams. Each stream has a status flag word to indicate whether an error has occurred and what type of error has occurred. This processing technology is the same as the format control flag word.

static constexpr _Iostate goodbit = static_cast<_Iostate>(0x0);
static constexpr _Iostate eofbit  = static_cast<_Iostate>(0x1);
static constexpr _Iostate failbit = static_cast<_Iostate>(0x2);
static constexpr _Iostate badbit  = static_cast<_Iostate>(0x4);

In the source code, you can see the four states of the file: goodbit, eofbit, failbit and badbit. Their default values are 0, 1, 2 and 4 respectively.

The IOS class provides the following member functions to detect or set the state of the stream:

file. good(); //  normal
file. eof(); //  The input stream ends with and no characters can be read in
file. fail(); //  The last read / write operation failed, but the stream is still available
file. bad(); //  Invalid read / write operation, stream is no longer available

The rdstate() function of IOS can obtain the final state of the file. There may be only one state of the file, such as:

rdstate() = goodbit;

There can also be a variety of file states, such as:

rdstate() = eofbit | failbit;

Use the | operator to calculate the final file state. So, how to judge the status of the current file?

file.good() = rdstate() & goodbit;
file.eof() = rdstate() & eofbit;
file.fail() = rdstate() & failbit;
file.bad() = rdstate() & badbit;

Use the & operator to determine what state the file is.

It is also very simple to remove the state and call directly



(6) Addition of files

In the file write operation, in addition to completely overwriting and rewriting the contents of the output file, you can also directly append data to the end of the file.

ofstream outfile("text.txt", ios::app);

In the above code, the second IOS:: app of the file output stream means to write data in the form of append.

The addition method can also be implemented by seekp. The code is as follows:

fstream iofile("test.txt",ios::in | ios::out);
If (iofile) // if the file exists
    iofile. seekp(0, ios::end); //  Move the file pointer to the end
    iofile << endl; //  Write newline
    iofile << "zhangsan"; //  Write new text
(7) Judgment of the end of the file

When operating a file, you often need to judge whether the file is finished or not, which can be achieved by using EOF ().
In addition, it can also be judged by other methods, such as using the get () method of the stream. If the file pointer points to the end of the file, the get () method returns – 1 if it can’t get the data, which can also be used as a method to judge the end.

(8) Function to set file pointer position

To realize the function of reading and writing files at the specified position, first understand how the file pointer moves. The functions used to set the position of the file pointer are as follows:

Seekg: the number of displacement bytes, and the relative position is used to move the pointer in the input file;
Seekp: the number of displacement bytes, and the relative position is used to move the pointer in the output file;
Tellg: used to find the file pointer position in the input file;
Tellp: used to find the file pointer position in the input file;

The number of displacement bytes is the displacement of the moving pointer, and the relative position is the reference position. The values are as follows:

IOS:: beg: file header;
IOS:: end: end of file;
IOS:: cur: current position of file pointer;
(9) Delete file

Use remove (file) to delete files. Its return value type is int. if the return value is 0, the deletion succeeds. If it is – 1, the deletion fails.

The demo code is as follows:

if (!remove("test.txt")) 
    Cout < < file deleted < < endl;
    Cout < < delete failed < < endl;

[end of this chapter…]