C/C++ file read and write operations (binary files & text files)

1. C++ file read and write operations

The included headers are fstream, ifstreamis the file input stream, ofstreamand is the file output stream.
Open the file as ofstream fout(file_name, ios::out|...|...)or ofstream fout; fout.open(file_name, ios::out|...|...).

open mode illustrate
ios::in Open the file for input; fail if the file does not exist, and open if the file exists. (ifstream is opened by default)
ios:out Open the file for output; create and open the file if it does not exist, or clear it if it exists. (ofstream is opened by default)
ios::nocreate It does not work when the file exists. When the file does not exist, it will force the file to not exist and not be created. This item is opened for the output file.
ios::noreplace Do not overwrite the file, and fail if the file exists when opening it. When the file does not exist, the parameter has no effect. This option has no effect on ios::in when the file exists, but works on ios::out, which fails to open when the file exists.
ios::binary The file is opened in text mode by default , and this mode is opened in binary mode.
ios::trunk If the file does not exist, it is invalid. If the file exists, first clear the contents inside.
ios::app All output is appended at the end of the file, and the read operation and write operation share the pointer, which has the characteristics of reading the file, and does not clear the file content when used in combination with ios::out.
ios::ate The initial position of the file pointer is at the end of the file.

1.1 C++ operating text files

1.1.1 Writing files
#include <iostream>
#include <fstream>
using namespace std;

int main()
{
    
    

    ofstream fout("out.txt",ios::out); //默认是ios::trunc
    /*读文件*/
    if(!fout.is_open())
    {
    
    
        exit(1);
    }
    char ch;
    while(!(EOF == (ch =getchar()))) //ctrl + z
    {
    
    
        fout << ch;
    }

    fout.close();

    return 0;

}
1.1.2 Reading files
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()
{
    
    

    ifstream fin("in.txt",ios::in);//默认是ios::trunc
    /*读文件*/
    if(!fin.is_open())
    {
    
    
        exit(1);
    }

    char ch;

    fin >> noskipws; //不跳过空格和回车
    //默认跳过空格和回车

    //读取单个字符
    /*while(!fin.eof())
    {
        fin >> ch;
        cout << ch;
    }*/
    //读取单个字符
    /*while(!(EOF == (ch = fin.get())))
    {
        cout << ch;
    }*/

    //读取一行字符串 getline
    string str;
    while(getline(fin, str))
    {
    
    
        cout << str <<"*"<<endl;
    }
    fin.close();

    return 0;
}

1.2 C++ operating binary files

The advantage of binary files over text files is that they take up less memory space and are easier to retrieve. For example, when storing structures or classes, the text file stores only simple text, which not only wastes space but also is inefficient. Because the number of bytes occupied by each object in the structure or class is different, even if the text file is sorted according to a certain value, it can only be searched from the beginning of the file to the end of the file, and there is no other good way.
But with binary storage, the number of bytes occupied by each structure or class is the same, and the object is directly written into the file, which is called a "record". Each object corresponds to a record. After sorting according to a certain value, you can Use algorithms such as binary search to search, which is much faster.
Reading and writing binary files cannot use cin coutstream data reading methods similar to and such. At this time, it is necessary to call the member functions of fstreamand to write data to the file, and the member functions of and to read data from the file.ofstreamwritefstreamifstreamread

1.2.1 Writing files

ostream & write(char* buffer, int count);

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class MyClass{
    
    
public:
    int a;
    char b[10];
    char c;
};

int main()
{
    
    

    ofstream fout("out.dat",ios::out | ios::binary);
    if(!fout.is_open()) exit(1);

    MyClass mc;
    while(cin >> mc.a >> mc.b >> mc.c)
    {
    
    
        fout.write((char*)&mc, sizeof(mc));//mc的地址就是要写入内存文件缓冲区的地址
    }
    fout.close();

    return 0;
}

1.2.2 Reading files

istream & read(char* buffer, int count);
int gcount();

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class MyClass{
    
    
public:
    int a;
    char b[10];
    char c;
};

int main()
{
    
    

    ifstream fin("out.dat",ios::in | ios::binary);
    if(!fin.is_open()) exit(1);

    MyClass mc;

    while(fin.read((char*)&mc, sizeof(mc)))
    {
    
    
        int cnt_bytes = fin.gcount();//查看刚才读取了多少字节
        cout << cnt_bytes<<endl;
        cout << mc.a << " "<<mc.b << " "<< mc.c<<endl;
    }

    fin.close();

    return 0;
}

Why is b defined as a variable of string type in MyClass, but it cannot be read when reading the out.dat file?

2. C file read and write operations

open mode illustrate
r Open the file read-only, the file must exist.
r+ Open the file for reading and writing, the file must exist.
rb+ read-write opens a binary file, allowing data to be read and written.
rw+ read-write opens a text file, allowing reading and writing.
w Open the write-only file. If the file exists, the file length will be cleared to 0, that is, the content of the file will disappear. Create the file if it does not exist.
w+ Open a readable and writable file. If the file exists, the file length will be cleared to zero, that is, the content of the file will disappear. Create the file if it does not exist.
a Open the file for writing as an append. If the file does not exist, it will be created. If the file exists, the written data will be added to the end of the file, that is, the original content of the file will be preserved. (EOF character reserved)
a+ Open the file for reading and writing in an append mode. If the file does not exist, it will be created. If the file exists, the written data will be added to the end of the file, that is, the original content of the file will be retained. (The original EOF character is not retained)
wb Write-only Open or create a new binary file; only write data is allowed.
wb+ read-write opens or creates a binary file, allowing both reading and writing.
ab+ Read-write opens a binary file, allowing data to be read or appended to the end of the file.
at+ Open a file called string, a means append, that is to say, when the writing process is written, the existing content of the original file is written instead of overwriting from the beginning. t means that the type of the opened file is a text file, and the + sign means that the file is edited Both read and write.

2.1 C operating text files

2.1.1 Writing files
#include<stdio.h>
#include<stdlib.h>

int main()
{
    
    
    FILE *fp = fopen("out.txt", "w");//只写方式打开文件

    if(!fp)
        exit(1);//写文件失败

    int a;
    while(scanf("%d", &a))
    {
    
    
        fprintf(fp, "%d ",a);
    }

    fclose(fp);

    return 0;
}
2.1.2 Reading files
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    
    
	FILE* fp = fopen("in.txt", "r");//只读方式打开文件

	if (!fp)
		exit(1);//读文件失败

	int mode = 1;
	printf("mode为1, 按字符读入并输出; mode为2, 按行读入并输出;\n请输入mode: ");
	scanf("%d", &mode);
	if (mode == 1)
	{
    
    
		//按字符读入并直接输出
		char ch;//读取的字符
		/*while (EOF != (ch = fgetc(fp)))//是否为文件结束符
			printf("%c", ch);*/
        while(EOF != fscanf(fp, "%c", &ch))
            printf("%c", ch);
	}
	else if (mode == 2)//按行读入并输出
	{
    
    
		char line[100];
		memset(line, 0, 100);
		while (!feof(fp))
		{
    
    
		    fgets(line, 100, fp);
			printf("%s", line); //输出
		}
	}

	fclose(fp);

	return 0;
}

2.2 C Manipulating Binary Files

2.2.1 Writing files

What should be noted here is that when writing structure data, because the variable is a character, so pay attention to eating the carriage returnchar c after each input of the structure , otherwise it will cause the input to fail, just like what I wrote in the code That way, use spaces to eat up preceding blank characters (including carriage return spaces, etc.).

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct MyStruct{
    
    
    int a;
    char b[10];
    char c;
}MyStruct;

int main()
{
    
    
	FILE* fp = fopen("test.dat", "wb+");//读写打开或建立一个二进制文件,允许读和写。

	if (!fp)
		exit(1);//写文件失败

	/*写int数据*/
	
    /*int a;
    while(scanf("%d", &a))
        fwrite(&a, sizeof(int), 1, fp);//写入int数据*/


	/*写结构体数据*/
    MyStruct ms;

    //先将结构体存储在结构体数组中
    //MyStruct ms[4];
    //MyStruct *p = ms;
    /*for(int i = 0; i < 4; i++,p++)
    {
        scanf(" %d", &p->a);
        scanf(" %s", p->b);
        scanf(" %c",&p->c);
    }*/
    //fwrite(ms, sizeof(MyStruct), 4, fp);
    //最后写到二进制文件

    //直接输入 以ctrl+D 结束输入
    while(scanf(" %d %s %c ", &ms.a, ms.b, &ms.c))
    //while(scanf(" %d", &ms.a) && scanf(" %s ", ms.b) && scanf(" %c ",&ms.c))
    {
    
    	//每次输入结束之后直接写入二进制文件
        fwrite(&ms, sizeof(MyStruct), 1, fp);
    }

	fclose(fp);

	return 0;
}

2.2.2 Reading files

You need to get the file size, otherwise you can only set the data length subjectively. It is not like C++ reads binary files to determine whether the reading is over by whether EOF is read.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct MyStruct{
    
    
    int a;
    char b[10];
    char c;
}MyStruct;

int main()
{
    
    
	fp = fopen("test.dat", "rb+");//读写打开一个二进制文件,允许读写数据。

	if (!fp)
		exit(1);//写文件失败

    fseek(fp, 0L, SEEK_END);//定位到文件尾
    int len = ftell(fp); //获取到文件大小 字节数
    rewind(fp);//文件指针复位 到文件头

    /*读int数据*/
    
    /*int buffer[100];
    memset(buffer, 0, sizeof(buffer)); //数组初始化为0
    fread(buffer, sizeof(int), 100, fp);//读取数据到buffer缓冲区中

    //读取的时候只能都读出来 或者一次读一个数据 但还是需要知道数据总长度
    for(int i = 0; i < len / sizeof(int); i++)
        printf("%d ", buffer[i]);
    printf("\n");

    int j = 0;
    while(j < len/sizeof(int))
    {
        fread(&buffer[j], sizeof(int), 1, fp);
        printf("%d \n",buffer[j]);
        j++;
    }*/

    /*读结构体数据*/
    
    int j = 0;
    MyStruct ms[100];
    while( j < len /sizeof(MyStruct))
    {
    
    
        fread(&ms[j], sizeof(MyStruct), 1, fp);
        printf("%d %s %c\n", ms[j].a, ms[j].b, ms[j].c);
        j++;
    }
	fclose(fp);

	return 0;
}

Guess you like

Origin blog.csdn.net/qq_41139677/article/details/108928989