C + + common file stream operations

Posted by kamurj on Wed, 01 Dec 2021 05:39:26 +0100

1. Open the file

1.1 fstream type

#include <fstream>  
ofstream         //File write operation memory write storage device   
ifstream         //File read operation, the storage device reads the area into memory  
fstream          //Read / write operation. Open files can be read / written

1.2 function prototype of open()

void open ( const char * filename,  
            ios_base::openmode mode = ios_base::in | ios_base::out );

void open(const wchar_t *_Filename,
        ios_base::openmode mode= ios_base::in | ios_base::out,
        int prot = ios_base::_Openprot);
parametermeaning
filenameOperation file name
modeHow to open a file
protOpen file properties

1.3 opening mode

The file opening method is defined in ios class (so the base class of streaming I/O). There are several common methods:

parametermeaning
ios::inOpen file for input (read)
ios::outOpen file for output (write)
ios::ateInitial location: end of file
ios::appAll output is appended to the end of the file
ios::truncIf the file already exists, delete the file before creating it again
ios::binaryBinary mode

1.4 properties of open file

The open file attribute is also defined in the ios class:

parametermeaning
0Normal file, open operation
1Read only file
2Implied file
4System file

1.5 example code

#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
 
int main()
{
    ofstream inFile;
    /*ios::trunc Indicates that the file will be emptied before opening the file. Because it is written, it will be created if the file does not exist*/
    inFile.open("inFile.txt",ios::trunc);
 
    int i;
    char a='a';
    for(i=1;i<=26;i++)//Write 26 numbers and English letters into the file
    {
        inFile<<setw(2)<<i<<"\t"<<a<<"\n";
        a++;
    }
    inFile.close();//Close file
}

2. Reading and writing of text files

2.1 example of writing files

// writing on a text file  
 #include <fstream.h>  
 
 int main () 
 {  
     ofstream out("out.txt");  
     if (out.is_open())   
    {  
         out << "This is a line.\n";  
         out << "This is another line.\n";  
         out.close();  
     }  
     return 0;  
 }  
//Result: write in out.txt:  
This is a line.  
This is another line   

2.2 example of file reading

// reading a text file  
   #include <iostream.h>  
   #include <fstream.h>  
   #include <stdlib.h>  
     
   int main () 
   {  
       char buffer[256];  
       ifstream in("test.txt");  
       if (! in.is_open())  
       { 
       cout << "Error opening file"; 
       exit (1);
       }  
       while (!in.eof() )  //eof returns true to the end of the file
       {  
           in.getline (buffer,100);  
           cout << buffer << endl;  
       }  
       return 0;  
   }  
   //The results are output on the screen  
    This is a line.  
    This is another line  

2.3 character by character and line by line reading

First, let's talk about the getline function. You need the header file #include < string >
Function prototype: istream & getline (istream & is, string & STR, char delim);
Where istream & is represents an input stream, such as cin;
String & str means to store the string read from the input stream in this string (you can name it yourself, str or anything);
char delim means stop reading when this character is encountered. If it is not set, the system defaults to '\ n', that is, carriage return line feed

#include <iostream>
#include <fstream>
using namespace std;
void testByChar()
{
    fstream testByCharFile;
    char c;
    testByCharFile.open("inFile.txt",ios::in);
    while(!testByCharFile.eof())
    {
        testByCharFile>>c;
        cout<<c;
    }
    testByCharFile.close();
}
void testByLine()
{
    char buffer[256];
    fstream outFile;
    outFile.open("inFile.txt",ios::in);
    cout<<"inFile.txt"<<"--- all file is as follows:---"<<endl;
    while(!outFile.eof())
    {
        outFile.getline(buffer,256,'\n');//getline(char *,int,char) indicates that 256 characters in the line or the line ends when a line break occurs
        cout<<buffer<<endl;
    }
    outFile.close();
}
int main()
{
   cout<<endl<<"Character by character read file: testByChar() "<<endl<<endl;
   testByChar();
   cout<<endl<<"Store the contents of each line of the file into a string, and then output the string: testByLine()"<<endl<<endl;
   testByLine();
}

2.4 count the number of text lines and read the content of a line

//How to count the number of lines of text and how to read a line of the file:
 
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
 
int CountLines(char *filename)
{
    ifstream in;
    int n=0;
    string tmp;
    in.open(filename,ios::in);//ios::in indicates that the file is read-only
    if(in.fail())//File open failed: return 0
    {
        return 0;
    }
    else//File exists
    {
        while(getline(in,tmp,'\n'))
        {
            n++;
        }
        in.close();
        return n;
    }
}
 
string ReadLine(char *filename,int line)
{
    int lines,i=0;
    string temp;
    fstream file;
    file.open(filename,ios::in);
    lines=CountLines(filename);
 
    if(line<=0)
        return "Error 1: Wrong number of rows, cannot be 0 or negative.";
    if(file.fail())
        return "Error 2: File does not exist.";
    if(line>lines)
        return "Error 3: The number of lines exceeds the file length.";
    
    while(getline(file,temp)&&i<line-1)
    {
        i++;
    }
    file.close();
    return temp;
}

int main()
{
    int line;
    char filename[]="inFile.txt";
    cout<<"The number of lines in this file is:"<<CountLines(filename)<<endl;
    cout<<"\n Please enter the number of rows to read:"<<endl;
    while(cin>>line)
    {
        cout<<"The first"<<line<<"The contents of the line are:"<<endl;
        cout<<ReadLine(filename,line);
        cout<<"\n\n Please enter the number of rows to read:"<<endl;
    }
}
/**********************************
The operation of the program is as follows:
The number of lines in the file is: 26
 Please enter the number of rows to read:
-3
 Line - 3 reads:
Error 1: Wrong number of rows, cannot be 0 or negative.
Please enter the number of rows to read:
4
 Line 4 reads:
 4      d
 Please enter the number of rows to read:
8
 Line 8 reads:
 8      h
 Please enter the number of rows to read:
26
 Line 26 reads:
26      z
 Please enter the number of rows to read:
33
 Line 33 reads:
Error 3: The number of lines exceeds the file length.
Please enter the number of rows to read:
66
 Line 66 reads:
Error 3: The number of lines exceeds the file length.
Please enter the number of rows to read:
^Z
**********************************/

2.5 read data into the array

//Read file data to temporary array
 
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
 
 
int CountLines(char *filename)
{
    ifstream ReadFile;
    int n=0;
    string tmp;
    ReadFile.open(filename,ios::in);//ios::in indicates that the file is read-only
    if(ReadFile.fail())//File open failed: return 0
    {
        return 0;
    }
    else//File exists
    {
        while(getline(ReadFile,tmp,'\n'))
        {
            n++;
        }
        ReadFile.close();
        return n;
    }
}
int main()
{
    ifstream file;
    int LINES;
    char filename[512]="inFile.txt";
    file.open(filename,ios::in);
    if(file.fail())
    {
        cout<<"file does not exist."<<endl;
        file.close();
    }
    else//File exists
    {
        LINES=CountLines(filename);
        int *tempInt=new int[LINES];
        char *tempChar=new char[LINES];
        int i=0;
        while(!file.eof()) //Read data to array
        {
 
            file>>tempInt[i];
            file>>tempChar[i];
            i++;
        }
        file.close(); //Close file
        for(i=0;i<LINES;i++)//Output array contents
            cout<<tempInt[i]<<"\t"<<tempChar[i]<<endl;
        delete []tempInt;
        delete []tempChar;
    }
}

3. Verification of state flags

  • bad() returns true if an error occurs during reading and writing
    For example, when we want to write to a file that is not open for writing, or when the device we want to write has no free space

  • fail()
    In addition to returning true in the same case as bad(), it also returns true in case of format error. For example, when you want to read an integer and get a letter

  • eof()
    Returns true if the read file reaches the end of the file

  • good()
    This is the most common: if calling any of the above functions returns true, this function returns false

To reset the status flag checked by the above member function, you can use the member function clear()

4. Get and put stream pointers

All I / O streams objects have at least one stream pointer:

  • ifstream, similar to istream, has a pointer called get pointer to the next element to be read.
  • ofstream, similar to ostream, has a pointer put pointer to the position where the next element is written.
  • Fsstream, similar to iostream, inherits both get and put

We can read or configure these stream pointers to read and write positions in the stream by using the following member functions:

  • tellg() and tellp()
    These two member functions return POS without passing in parameters_ The value of type (according to ANSI-C + + standard) is an integer representing the position of the current get stream pointer (with tellg) or put stream pointer (with tellp)

  • seekg() and seekp()
    This pair of functions is used to change the position of the stream pointers get and put, respectively. Both functions are overloaded into two different prototypes:

seekg ( pos_type position );
seekp ( pos_type position );

Using this prototype, the stream pointer is changed to point to an absolute position calculated from the file. The parameter type passed in is required to be the same as the return value type of the functions tellg and tellp.

seekg ( off_type offset, seekdir direction );
seekp ( off_type offset, seekdir direction );

Using this prototype, you can specify an offset calculated from a specific pointer determined by the parameter direction. It can be:

parametermeaning
ios::begDisplacement calculated from the beginning of the flow
ios::curThe displacement calculated from the current position of the stream pointer
ios::endDisplacement calculated from the end of the flow

The values of stream pointers get and put are different for the calculation methods of text file and binary file, because some special characters in text mode files may be modified. For this reason, it is recommended to always use the first prototype of seekg and seekp for files opened in text file mode, and do not modify the return value of tellg or tellp. For binary files, you can use these functions arbitrarily, and there should be no unexpected behavior.
Use example:

example:
file.seekg(0,ios::beg); //Position the file pointer to the beginning of the file
file.seekg(0,ios::end); //Position the file pointer to the end of the file
file.seekg(10,ios::cur); //Move the file pointer 10 bytes from the current position to the end of the file
file.seekg(-10,ios::cur); //Move the file pointer 10 bytes from the current position to the beginning of the file
file.seekg(10,ios::beg); //Position the file pointer 10 bytes from the beginning of the file
--------
Copyright notice: This article is CSDN Blogger「Wang Shihui」Original articles, follow CC 4.0 BY-SA Copyright agreement, please attach the original source link and this statement.
Original link: https://blog.csdn.net/wangshihui512/article/details/8921919

Get the size of a binary file:

// obtaining file size  
   #include <iostream.h>  
   #include <fstream.h>  
     
   const char * filename = "test.txt";  
     
   int main ()
    {  
       long l,m;  
       ifstream in(filename, ios::in|ios::binary);  
       l = in.tellg();  
       in.seekg (0, ios::end);  
       m = in.tellg();  
       in.close();  
       cout << "size of " << filename;  
       cout << " is " << (m-l) << " bytes.\n";  
       return 0;  
   }  
    
  //result:  
  size of example.txt is 40 bytes.  

5. Binary files

In binary files, using < < and > > and functions (such as getline) to input and output data by operators makes no practical sense, although they comply with syntax.

The file stream includes two member functions specially designed for sequential data reading and writing: write and read. The first function (write) is a member function of ostream, which is inherited by ofstream. Read is a member function of istream, which is inherited by ifstream. An object of class fstream has both functions. Their prototypes are:

write ( char * buffer, streamsize size );
read ( char * buffer, streamsize size );

Here, buffer is the address of a block of memory used to store or read data. The parameter size is an integer value indicating the number of characters to be read or written from the buffer.

Example of reading binary files:

// reading binary file  
    #include <iostream>  
    #include <fstream.h>  
      
    const char * filename = "test.txt";  
      
    int main () {  
        char * buffer;  
        long size;  
        ifstream in (filename, ios::in|ios::binary|ios::ate);  
        size = in.tellg();  
        in.seekg (0, ios::beg);  
        buffer = new char [size];  
        in.read (buffer, size);  
        in.close();  
          
        cout << "the complete file is in a buffer";  
          
        delete[] buffer;  
        return 0;  
    }  
    //Operation results:  
    The complete file is in a buffer  

6. Buffers and synchronization

When we operate on file streams, they are associated with a streambuf f type buffer. This buffer is actually a piece of memory space as a medium for streams and physical files. For example, for an output stream, every time the member function put (write a single character) is called, this character is not directly written to the physical file corresponding to the output stream, but is first inserted into the buffer of the stream.

When the cache is flushed, all the data in it is either written to the physical medium (if it is an output stream) or simply erased (if it is an input stream). This process is called synchronization and occurs in any of the following situations:

  • When a file is closed: all caches that have not been completely written out or read will be synchronized before the file is closed.
  • When the cache buffer is full: the cache Buffers have a certain space limit. When the cache is full, it is automatically synchronized.
  • The control character clearly indicates that synchronization will occur when some specific control characters in the flow are encountered. These controllers include: flush and endl.
  • Explicitly call the function sync(): calling the member function sync() (without parameters) can trigger immediate synchronization. This function returns an int value equal to - 1, indicating that the stream has no associated cache or the operation has failed.

Topics: C++