C language · Input and output of files (detailed explanation of ten thousand characters)

insert image description here

The biggest reason for learning is to get rid of mediocrity. One day earlier, there will be more splendor in life; one day later, one day more mediocrity.

study diary

Table of contents

study diary

foreword

1. Basic knowledge about C files

1. What is a file

2. File name 

3. Classification of files

4. File buffer

5. File type pointer 

2. Open and close files

1. Open and close files

2. Open the data file with the fopen function 

3. Close the data file with the fclose function

3. Sequential reading and writing of data files

1. How to read and write characters to a file

 Functions to read and write a character

Example 1

Example 2

 Functions to read and write a string

2. How to read and write a string to a file 

Example 3

3. Read and write text files in a formatted way 

4. Read and write a set of data to the file in binary mode

5. Read attention

4. Randomly read and write data files

1. File location mark and its positioning

1. File location marker

2. Positioning of the file position mark 

example

5. Error detection of file reading and writing

1. ferror function 

2. clearerr function 

Notice


foreword

        File operation is a very practical operation. Let's take a look below! 

1. Basic knowledge about C files

1. What is a file

        There are different types of files. In programming, two types of files are mainly used:

(1) Program files. Including source program files (suffix .c), object files (suffix .obj), executable files (suffix .exe), etc. The content of such a file is program code.

(2) Data files. The content of the file is not a program, but data for reading and writing when the program is running, such as data output to disk (or other external devices) during the running of the program, or data read in during the running of the program. Such as a batch of student achievement data, data on goods transactions, etc.

        In order to simplify the user's operation of the input and output devices, so that the user does not have to distinguish between various input and output devices, the operating system treats all devices as files. From the perspective of the operating system, each input and output device connected to the host is regarded as a file. For example, the terminal keyboard is the input file, and the display screen and printer are the output files.

        A file generally refers to a collection of data stored on an external medium .

        The operating system manages data in units of files. Input and output is the process of data transmission, and data flows from one place to another like flowing water, so the input and output are often called stream (stream), that is, data flow. A flow represents the flow of information from a source to a destination. During input operations, data flows from the file to the computer's memory, and during output operations, data flows from the computer to the file (eg, printer, disk file).

         The C language regards a file as a sequence of characters (or bytes), that is, it consists of a character (or byte) sequence of data. An input and output stream is a stream of characters or bytes (the content is binary data). The data file of C is composed of a series of characters (or bytes), regardless of the boundary of the line, the separator will not be automatically added between two lines of data, and the access to the file is in units of characters (bytes). The start and end of the input and output data streams are only controlled by the program and not by physical symbols (such as carriage return and line feed), which increases the flexibility of processing. Such files are called streaming files. 

2. File name 

A file must have a unique file identifier for user identification and reference.

The file identification includes 3 parts: (1) file path; (2) file name trunk; (3) file suffix.

D:\CC\temp\file1.dat        

          ↓          ↓   ↓      

path trunk name suffix

The file path indicates the location of the file in the external storage device.

The naming rules for filename stems follow the naming rules for identifiers.

The file suffix is ​​used to indicate the nature of the file.

For convenience, the file identifier is often referred to as the file name, but it should be understood that the so-called file name at this time actually includes the above three parts, not just the main file name.

3. Classification of files

        According to the organizational form of data, data files can be divided into ASCII files and binary files. Data is stored in binary form in the memory. If it is output to the external memory without conversion, it is a binary file. It can be considered as an image of the data stored in the memory, so it is also called an image file. If it is required to store in the form of ASCII code on the external storage, it needs to be converted before storage. ASCII files are also called text files, and each byte stores the ASCII code of a character.

4. File buffer

         The ANSI C standard uses a "buffer file system" to process data files. The so-called buffer file system means that the system automatically creates a file buffer in the memory area for each file being used in the program. Data output from memory to disk must be sent to the buffer in memory first, and then sent to disk together after the buffer is filled. If data is read from the disk to the computer, a batch of data is input from the disk file to the memory buffer (full buffer), and then the data is sent from the buffer to the program data area one by one (to the program variable). This is done to save access time and improve efficiency. The size of the buffer is determined by each specific C compilation system.

        Explanation : Each file has only one buffer in memory. When outputting data to the file, it is used as the output buffer, and when inputting data from the file, it is used as the input buffer.

5. File type pointer 

        In the cache file system, the key concept is "file type pointer", referred to as "file pointer". Each used file opens up a corresponding file information area in the memory, which is used to store the relevant information of the file (such as the name of the file, the status of the file and the current location of the file, etc.). This information is stored in a structure variable. The structure type is declared by the system and named FILE.

typedef struct
{	short level;				//缓冲区“满”或“空”的程度
	unsigned flags;			//文件状态标志
	char fd;					//文件描述符
	unsigned char hold; 		//如缓冲区无内容不读取字符
	short bsize;				//缓冲区的大小
	unsigned char*buffer;	//数据缓冲区的位置
	unsigned char*curp;		//文件位置标记指针当前的指向
	unsigned istemp;		//临时文件指示器
	short token;				//用于有效性检查
}FILE;
FILE *fp;
//定义一个指向FILE类型数据的指针变量

         You can make fp point to the file information area of ​​a certain file (it is a structure variable), and the file can be accessed through the information in the file information area. That is to say, the file associated with it can be found through the file pointer variable. If there are n files, n pointer variables should be set to point to n FILE type variables to realize access to n files. For convenience, this kind of pointer variable pointing to the file information area is usually referred to as a pointer variable pointing to the file.

2. Open and close files

1. Open and close files

        The file should be "opened" before reading or writing to it, and should be "closed" after use. The so-called "opening" refers to establishing a corresponding information area (used to store information about the file) and a file buffer (used to temporarily store input and output data) for the file. When writing a program, when opening a file, generally specify a pointer variable to point to the file, that is, establish a connection between the pointer variable and the file, so that the file can be read and written through the pointer variable. The so-called "closing" refers to revoking the file information area and file buffer, so that the file pointer variable no longer points to the file, and obviously the file cannot be read or written.

2. Open the data file with the fopen function 


fopen(file name, use file method);


FILE *fp;				//定义一个指向文件的指针变量fp
fp=fopen(″a1″,″r″);	//将fopen函数的返回值赋给指针变量fp

 When opening a file, notify the compilation system of the following three information:

① The name of the file to be opened, that is, the name of the file to be accessed

② How to use the file ("read" or "write", etc.)

③ Let which pointer variable point to the opened file

 use file

file usage

meaning

If the specified file does not exist

"r" (read-only)

To enter data, open an existing text file

go wrong

"w" (write only)

To output data, open a text file

create new file

“a” (append)

Add data to the end of the text file

go wrong

"rb" (read-only)

To enter data, open a binary file

go wrong

"wb" (write only)

To output data, open a binary file

create new file

“ab” (append)

Add data to the end of the binary file

go wrong

"r+" (read and write)

Open a text file for reading and writing

go wrong

"w+" (read and write)

Create a new text file for reading and writing

create new file

"a+" (read and write)

Open a text file for reading and writing

go wrong

"rb+" (read and write)

Open a binary file for reading and writing

go wrong

"wb+" (read and write)

Create a new binary file for reading and writing

create new file

"ab+" (read and write)

Open a binary file for reading and writing

go wrong

(1) The file opened with "r" mode can only be used for input to the computer but not for output data to the file, and the file should already exist and contain data, so that the program can read data from the file. Cannot open a non-existent file in "r" mode, otherwise an error occurs.

(2) The file opened with "w" can only be used to write data to the file (that is, the output file), but not to input to the computer. If the file does not exist, create a new file with the specified name before opening the file. If there is already a file named with this file name, delete the file before opening the file, and then create a new file.

(3) If you want to add new data to the end of the file (do not want to delete the original data), you should open it with "a". But at this time, you should ensure that the file already exists; otherwise, you will get an error message. An implicit "file reading and writing position mark" is automatically set in each data file, and the position it points to is the current reading and writing position. If the "file read and write position mark" is at the beginning of the file, the next read and write is the data at the beginning of the file. Then the "file reading and writing position mark" automatically moves to the next reading and writing position, so as to read and write the next data. When a file is opened for append, the file read/write mark is moved to the end of the file. (4) Files opened with "r+", "w+" and "a+" can be used for both input and output data.

(5) If the task of "opening" cannot be realized, the fopen function will return a null pointer value NULL.

(6) The C standard recommends using the file usage methods listed in Table 10.1 to open text files or binary files, but some C compilation systems currently in use may not fully provide all these functions, and you need to pay attention to the regulations of the system used.

(7) There are 12 file usage methods, 6 of which add the letter b after the first letter (such as rb, wb, ab, rb+, wb+, ab+), b means binary mode. In fact, there is only one difference between with b and without b, that is, the handling of newlines. Since the newline can be realized with a '\n' in the C language, in order to realize the newline in the Windows system, two characters of "carriage return" and "newline" must be used, namely '\r' and '\n'. Therefore, if you use a text file and open it with "w", when outputting to the file, when a newline character '\n' is encountered, the system will convert it into two characters '\r' and '\n' , otherwise, when viewing the file in the Windows system, each line will be connected into one piece and cannot be read. Similarly, if there is a text file and it is opened with "r", when reading from the file, if two consecutive characters '\r' and '\n' are encountered, convert them into one character '\n'. If you are using binary files, no such conversion is required when reading and writing to the file. Adding b means that the binary file is used, and the system will not convert it.

(8) If the "wb" file usage method is used, it does not mean that the data stored in the memory in ASCII format will be automatically converted into binary format when the file is output. The output data format is determined by the read and write statements used in the program. For example, the fscanf and fprintf functions are used for input and output in ASCII mode, while the fread and fwrite functions are used for binary input and output.

(9) Three standard stream files can be used in the program - standard input stream, standard output stream and standard error output stream. The system has specified the corresponding relationship with the terminal for these 3 files. The standard input stream is the input from the terminal, the standard output stream is the output to the terminal, and the standard error output stream is the error message sent to the terminal when the program fails. The system automatically opens these 3 standard stream files when the program starts running.

3. Close the data file with the fclose function


                                fclose(file pointer); fclose(fp); 


        A file should be closed after use to prevent it from being misused. "Close" is to revoke the file information area and file buffer, so that the file pointer variable no longer points to the file, that is, the file pointer variable is "decoupled" from the file, and the original associated file cannot be read or written through the pointer. Operation, unless opened again, make the pointer variable point to the file again. If you end the program without closing the file, you will lose data. Because, when writing data to a file, the data is first output to the buffer, and it is not officially output to the file until the buffer is full. If the program ends when the buffer is not filled with data, the data in the buffer may be lost.

        When using the fclose function to close a file, first output the data in the buffer to the disk file, and then cancel the file information area. Some compilation systems will automatically write the data in the buffer to the file before the program ends, thus avoiding this problem, but you should still develop the habit of closing all files before the program terminates. The fclose function also returns a value. When the close operation is successfully performed, the return value is 0; otherwise, EOF (-1) is returned. 

3. Sequential reading and writing of data files

1. How to read and write characters to a file

 Functions to read and write a character

Function name

calling form

Function

return value

fgetc

fgetc(fp)

read a character from the file pointed to by fp

If the read is successful, it will bring back the characters read, and if it fails, it will return the end-of-file flag EOF (ie -1)

fputc

fputc(ch,fp)

Write the character ch to the file pointed to by the file pointer variable fp

If the output is successful, the return value is the output character; if the output fails, it returns EOF (ie -1)

        The first letter f of fgetc stands for file (file), the middle get means "get", and the last letter c means character (character). The meaning of fgetc is very clear: read a character from the file. fputc is also similar. 

Example 1

        Enter some characters from the keyboard and send them to disk one by one until the user enters a "#". 

#include <stdio.h>
#include <stdlib.h>
int main()
{	FILE *fp;                     				//定义文件指针fp
	char ch,filename[10];
	printf("请输入所用的文件名: ");   
	scanf("%s",filename);        			//输入文件名
	getchar();                  		 		//用来消化最后输入的回车符
	if((fp=fopen(filename,"w"))==NULL)	//打开输出文件并使fp指向此文件
	{	printf("cannot open file\n");  	//如果打开出错就输出“打不开”
		exit(0);                       			//终止程序
	}
	printf("请输入一个准备存储到磁盘的字符串(以#结束): ");
	ch=getchar();        					//接收从键盘输入的第一个字符
	while(ch!='#')        					//当输入′#′时结束循环
	{	fputc(ch,fp); 					//向磁盘文件输出一个字符
		putchar(ch);					//将输出的字符显示在屏幕上
		ch=getchar(); 					//再接收从键盘输入的一个字符
	}
	fclose(fp);						//关闭文件
	putchar(10); 						//向屏幕输出一个换行符 
	return 0;
}

Example 2

        Copies information from one disk file to another. Now it is required to copy the contents of the file1.dat file created in the above example to another disk file file2.dat.

#include <stdio.h>
#include <stdlib.h>
int main()
{	FILE *in,*out; 						//定义指向FILE类型文件的指针变量
	char ch,infile[10],outfile[10];			//定义两个字符数组,分别存放两个数据文件名
	printf("输入读入文件的名字:");
	scanf("%s",infile);					//输入一个输入文件的名字
	printf("输入输出文件的名字:");
	scanf("%s",outfile); 					//输入一个输出文件的名字
	if((in=fopen(infile,"r"))==NULL)		//打开输入文件
	{	printf("无法打开此文件\n");	exit(0);	}
	if((out=fopen(outfile,"w"))==NULL)	//打开输出文件
	{	printf("无法打开此文件\n");	exit(0);	}
	ch=fgetc(in);          				//从输入文件读入一个字符,赋给变量ch
	while(!feof(in))       					//如果未遇到输入文件的结束标志
	{	fputc(ch,out);      				//将ch写到输出文件
		putchar(ch);        				//将ch显示到屏幕上
		ch=fgetc(in);       				//再从输入文件读入一个字符,赋给变量ch
	}
	putchar(10);						//显示完全部字符后换行
	fclose(in); 						//关闭输入文件
	fclose(out);						//关闭输出文件
	return 0;
}

 Functions to read and write a string

Function name

calling form

Function

return value

fgets

fgets(str,n,fp)

Read a string of length (n-1) from the file pointed to by fp and store it in the character array str

If the read is successful, the address str will be returned, and if it fails, NULL will be returned

fputs

fputs(str,fp)

Write the string pointed to by str to the file pointed to by the file pointer variable fp

If the output is successful, return 0; otherwise, return a non-zero value

        The last letter s in fgets represents a string (string). The meaning of fgets is: read a string from a file. 

2. How to read and write a string to a file 

The function prototype of the fgets function is char *fgets(char *str, int n, FILE *fp);

Its role is to read a string from a file. Calling can be written in the following form:

fgets(str,n,fp);

        Among them, n is the number of characters required, but actually only n-1 characters are read from the file pointed to by fp, and then a '\0' character is added at the end, so that the resulting string has a total of n characters , put them into the character array str. If a newline character "\n" or the end-of-file character EOF is encountered before reading n-1 characters, the reading ends, but the encountered newline character "\n" is also read as a character. If the execution of the fgets function is successful, the return value is the address of the first element of the str array. If the end of the file is encountered at the beginning or an error occurs in reading data, NULL is returned.

The function prototype of the fputs function is int fputs (char *str, FILE *fp);

Its function is to output the string pointed to by str to the file pointed to by fp. can be written as

fputs("China",fp);

        Output the string "China" to the file pointed to by fp. The first parameter in the fputs function can be a string constant, a character array name, or a character pointer. '\0' at the end of the string is not output. If the output is successful, the function value is 0; when it fails, the function value is EOF (ie -1).

        The functions of fgets and fputs are similar to the functions of gets and puts, except that gets and puts use the terminal as the read and write object, while fgets and fputs use the specified file as the read and write object.

Example 3

        Read in several strings from the keyboard, sort them in alphabetical order, and then send the sorted strings to a disk file for storage.

#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
int main()
{	FILE *fp;
	char str[3][10],temp[10];
	//str是用来存放字符串的二维数组,temp是临时数组
	int i,j,k,n=3;
	printf("Enter strings:\n");	//提示输入字符串
	for(i=0;i<n;i++) 
		gets(str[i]);			//输入字符串
	for(i=0;i<n-1;i++)			//用选择法对字符串排序
	{	k=i;
		for(j=i+1;j<n;j++)
			if(strcmp(str[k],str[j])>0) k=j;
		if(k!=i)
		{	strcpy(temp,str[i]);
			strcpy(str[i],str[k]);
			strcpy(str[k],temp);}
	}
	if((fp=fopen("D:\\CC\\string.dat","w"))==NULL)	//打开磁盘文件
	//′\′为转义字符的标志,因此在字符串中要表示′\′用′\\′
	{
		printf("can′t open file!\n");
		exit(0);
	}
	printf("\nThe new sequence:\n");
	for(i=0;i<n;i++)
	{	fputs(str[i],fp);fputs("\n",fp);
		//向磁盘文件写一个字符串,然后输出一个换行符
		printf("%s\n",str[i]);		//在屏幕上显示
	}
	return 0;
}

3. Read and write text files in a formatted way 

        You can format the input and output of the file. At this time, you need to use the fprintf function and the fscanf function. As you can see from the function name, they just add a letter f in front of printf and scanf. Their functions are similar to the printf function and scanf function, and they are both formatted read and write functions. There is only one difference: the read and write objects of fprintf and fscanf functions are not terminals but files. They are generally called as:


                                        fprintf(file pointer, format string, output list);

                                        fscanf(file pointer, format string, input list);


fprintf (fp,″%d,%6.2f″,i,f);	//将int型变量i和float型变量f的值按%d和%6.2f的格式输出到fp指向的文件中

fscanf (fp,″%d,%f″,&i,&f);
//磁盘文件上如果有字符“3,4.5”,则从中读取整数3送给整型变量i,读取实数4.5送给float型变量f

4. Read and write a set of data to the file in binary mode

         The C language allows reading a block of data from a file with the fread function, and writing a block of data to the file with the fwrite function. When reading and writing, it is performed in binary form. When writing data to the disk, a group of data in the memory is directly copied to the disk file without conversion, and when reading, the contents of several bytes in the disk file are also read into the memory in batches.

fread(buffer, size, count, fp);

fwrite(buffer, size, count, fp);

buffer: is an address. For fread, it is the address of the memory area used to store the data read from the file. For fwrite, it is to output the data in the storage area starting from this address to the file (the above refers to the starting address).

size: The number of bytes to read and write.

count: How many data items to read and write (the length of each data item is size).

fp: FILE type pointer. 

5. Read attention

(1) Data storage method Text method: Data is stored in the file in character mode (ASCII code). For example, the integer 12 occupies 2 bytes when sent to the file instead of 4 bytes. Data saved in text format is easy to read. Binary mode: The data is copied to the file as it is stored in memory. For example, the integer 12 occupies 4 bytes when sent to the file and in memory.

(2) Classification of files Text files (ASCII files): All of the files are ASCII characters. Binary file: The data in the memory is copied to the file in a binary manner, which is called a binary file, that is, an image file.

(3) Opening method of the file Text method: the method without b, the newline character is converted when reading and writing the file. Binary mode: In the mode with b, newline characters are not converted when reading and writing files.

(4) File reading and writing functions Text reading and writing functions: functions used to read and write character data to text files (such as fgetc, fgets, fputc, fputs, fscanf, fprintf, etc.). Binary read and write functions: functions used to read and write binary data to binary files (such as getw, putw, fread, fwrite, etc.).

4. Randomly read and write data files

        Sequential reading and writing of files is relatively easy to understand and easy to operate, but sometimes it is not efficient. Random access does not read and write according to the order of physical positions of data in the file, but can access data at any position. Obviously, this method is much more efficient than sequential access.

1. File location mark and its positioning

1. File location marker

        In order to control reading and writing, the system sets a file reading and writing position mark (referred to as file position mark or file mark) for each file, which is used to indicate "the position of the next character to be read and written next". Under normal circumstances, when reading and writing character files sequentially, the file position mark points to the beginning of the file. At this time, if the file is read/written, after the first character is read/written, the order of the file position mark moves backward. A position, when the next read/write operation is performed, the second character pointed to by the position mark is read or written. And so on, until the end of the file is encountered, at this time the file position mark is after the last data. Streaming files can be read and written sequentially or randomly. The key is to control the position mark of the file. If the file position mark is moved in byte position order, it is sequential read and write. If the file position mark can be moved to any position as needed, random read and write can be realized. The so-called random reading and writing means that after reading and writing the previous character (byte), it is not necessary to read and write the subsequent character (byte), but can read and write the required character (byte) at any position in the file. ). That is, the order of reading and writing data to a file is generally inconsistent with the physical order of the data in the file. Data can be written anywhere, and data can be read anywhere.

2. Positioning of the file position mark 

        Use the rewind function to make the file position mark point to the beginning of the file. The function of the rewind function is to make the file position mark return to the beginning of the file. This function has no return value.

        Use the fseek function to change the file position mark, fseek(file type pointer, displacement, starting point); the fseek function is generally used for binary files.

fseek (fp,100L,0);		//将文件位置标记向前移到离文件开头100个字节处
fseek (fp,50L,1); 		//将文件位置标记向前移到离当前位置50个字节处
fseek (fp,-10L,2);		//将文件位置标记从文件末尾处向后退10个字节

        Use the ftell function to measure the current position of the file position mark: the function of the ftell function is to obtain the current position of the file position mark in the streaming file, which is represented by the displacement relative to the beginning of the file. If an error occurs when calling the function (for example, the file pointed to by fp does not exist), the return value of the ftell function is -1L.

example

        There is a disk file with some information in it. It is required to display its content on the screen for the first time, and copy it to another file for the second time.

#include<stdio.h>
int main()
{	char ch;
	FILE *fp1,*fp2;
	fp1=fopen("file1.dat","r");	//打开输入文件
	fp2=fopen("file2.dat","w");	//打开输出文件
	ch=getc(fp1);				//从file1.dat文件读入第一个字符
	while(!feof(fp1))			//当未读取文件尾标志
	{	putchar(ch);			//在屏幕输出一个字符
		ch=getc(fp1);			//再从file1.dat文件读入一个字符
	}
	putchar(10);				//在屏幕执行换行
	rewind(fp1);				//使文件位置标记返回文件开头
	ch=getc(fp1);				//从file1.dat文件读入第一个字符
	while(!feof(fp1))			//当未读取文件尾标志
	{	fputc(ch,fp2);			//向file2.dat文件输出一个字符
		ch=fgetc(fp1);			//再从file1.dat文件读入一个字符
	}
	fclose(fp1);fclose(fp2);
	return 0;
}

5. Error detection of file reading and writing

1. ferror function 

 ferror(fp);

        When calling various input and output functions (such as putc, getc, fread, fwrite, etc.), if an error occurs, in addition to the reflection of the function return value, you can also use the ferror function to check. If ferror returns a value of 0 (false), it means that no error occurred; if it returns a non-zero value, it means that an error occurred. 

2. clearerr function 

        The role of clearerr is to set the file error flag and the end of file flag to 0. Assuming an error occurs while calling an input-output function, the ferror function evaluates to a non-zero value. The clearerr(fp) should be called immediately to make the value of ferror(fp) become 0 for the next detection. As long as the file read and write error flag appears, it remains until the clearerr function or rewind function is called on the same file, or any other input and output function.

Notice

        Each call to the input/output function for the same file will generate a new value of the ferror function, so the value of the ferror function should be checked immediately after calling an input/output function, otherwise the information will be lost. When the fopen function is executed, the initial value of the ferror function is automatically set to 0.

Guess you like

Origin blog.csdn.net/m0_63794226/article/details/126673668