6 C language file operation
6.1 documents
what is a document? In short, a file is something used to store data. The file we refer to refers to the file saved in the disk. Of course, the file can also be saved in the optical disk, U SB flash disk and other devices 1.
Using files has the following benefits:
(1) It can save data for a long time. The stored data can be used for many times and will not disappear due to power failure 1.
(2) The use of files is convenient for data management and retrieval, and the operating system takes files as a unit to manage the data in the disk 2.
6.1.1 document type
in program design, we generally talk about two kinds of files: program file and data file. Program files include source program files (the source program suffix of c language is. c), object files (the suffix is. obj), and executable programs (the suffix is. exe). When the program is running, the data used for reading and writing can be saved in the data file, and the content saved in the data file can also be code text. What is discussed here is the data file.
according to the organization form of data, data files are divided into text files and binary files. The way to distinguish between text files and binary files is to view the data in the file, that is, the type of the file is determined only after the data in the file is determined. If the data is stored outside 3 If it is stored in a file in ASCII code, the file is a text file. Binary data in memory. If the output without conversion is saved to an external file, the file is a binary file.
teach you a little skill. Open a file with a text editor (such as Notepad). If you see garbled code, it means that the file is a binary file. For example, the general suffix is pdf files are binary files 4 , as shown in Figure 6.1.1, a PDF file opened with Notepad shows garbled code. Usually we use PDF reader to open PDF files. The reason why the content is normal is that the PDF reader converts the data into the content we can understand.
6.1.2 file name
a file should have a unique file ID for user identification and reference. For convenience, the file ID is often referred to as the file name.
the file name includes three parts: file path + file name trunk + file suffix
For example: C: \ code \ test txtwhere c:\code \ is the file path, test is the file name, and txt is a file suffix. Generally, it is easy to ignore the path of the file, but it is indispensable for the file. The path of the file is usually specified for the reference file, unless the file is in the current folder. The file suffix can be omitted. The suffix cannot determine the file type. The function of the suffix is usually used for software parsing. In other words, the suffix determines the default opening method of the file.
6.2 data storage
how is data stored in files?
there are two types of data. All character data are stored in ASCII, and numerical data can be stored in ASCII or binary.
as shown in Figure 6.2.1, there is a numerical data 10000. If it is output to the disk in the form of ASCII code, the disk occupies 5 bytes (one byte for each character), while if it is output in binary form, it only occupies 4 bytes on the disk (VS 2019 test result).
In the following let's verify with the program and write the numerical data 10000 to the file test in binary form txt
Figure 6.2.2 test Txt file#include <stdio.h> int main() { int a = 10000; FILE* pf = fopen("test.txt", "wb"); fwrite(&a, 4, 1, pf);//Write to file in binary form fclose(pf); pf = NULL; return 0; }
as shown in Figure 6.2.2, you can see that the test is generated in the disk (i.e. in the folder where the project is located) Txt file. If you use Notepad to open test Txt file, you can see from figure 6.2.3 that the file is garbled because test Txt is a binary file, so I can't understand it.
we can view this file in the visual studio compiler so that we can understand it. The operation is as follows:
first test Add to TXT project.
change test in the project Txt.
after setting, double-click to open test Txt file.
we can see that vs2019 displays binary data 10000 in hexadecimal. At this time, we can understand that the data is stored in small end byte order 5 of
6.3 buffer file system
6.3.1 file buffer
the ANSIC standard uses "buffer file system" to process data files. As shown in Figure 6.3.1, in the buffer file system, the operating system automatically opens up a "file buffer" in memory for each file being used in the program. The file buffer includes output buffer and input buffer. If data is output from memory to disk, it will be sent to the output buffer in memory first. When the buffer is full, the data will be sent to disk together. If the memory reads data from the disk, first read the data from the disk file, and then put the data in the input buffer. When the data fills the buffer or refreshes the buffer, then send the data from the buffer to the program data area in the memory one by one. The size of the buffer is determined by the C compilation system.
6.3.2 document pointer
in the buffered FILE system, the key concept is "FILE type pointer", which is referred to as "FILE pointer". Each used FILE opens up a corresponding FILE information area in the memory to store the relevant information of the FILE (such as the name of the FILE, the status of the FILE, the current location of the FILE, etc.). The FILE information area is described by a structure variable, which is declared by the system and named FILE.
FILE types of different C compilers contain different contents, but they are similar. For example, stdio.net provided by VS2008 compilation environment The H header FILE contains the following FILE type declarations:
struct _iobuf { char *_ptr; int _cnt; char *_base; int _flag; int _file; int _charbuf; int _bufsiz; char *_tmpfname; }; typedef struct _iobuf FILE
whenever a FILE is opened, the system will automatically create a variable of FILE structure according to the situation of the FILE and fill in the information in it. Users don't have to care about the details. Generally, the variables of this FILE structure are maintained through a FILE pointer, which is more convenient to use.
Next, we can create a pointer variable of FILE *:
FILE* pf;// File pointer variable
above, PF defined is a pointer variable pointing to FILE type, which can make pf point to the FILE information area of a FILE (a structure variable). The FILE can be accessed through the information in the FILE information area. That is, the corresponding FILE can be operated through the FILE pointer variable. So how to use the FILE pointer to operate the FILE? The operation of files is nothing more than reading, writing, deleting and renaming. The FILE should be opened before reading and writing, and closed after the operation.
6.4 opening and closing of documents
ANSIC stipulates to use fopen function to open the FILE and fclose to close the FILE. In the program, when opening a FILE, a pointer variable of FILE * will be returned to point to the FILE, which is equivalent to establishing the relationship between the pointer and the FILE. For example:
FILE * fopen ( const char* filename, const char* mode ); int fclose ( FILE* stream );//Close file
where filename is the file name and mode is the opening mode. The options of opening mode are shown in the following table.
the following routine opens the file in write only mode,
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> int main() { FILE* pFile; pFile = fopen("myfile.txt", "w"); //Open file in write only mode if (pFile != NULL) { fputs("fopen example", pFile); //Writing character data to a text file fclose(pFile); } pFile = NULL; //Set the pointer to null to prevent wild pointer return 0; }
because there is an upper limit on the number of open files, you should close the file after the operation every time you open the file, otherwise too many open files will cause open failure. In stdio The maximum number of files that can be viewed in H is 20.
6.5 sequential reading and writing of documents
6.5.1 concept of flow
the following table is the file read-write function.
please pay attention to the concept of flow. Flow can be understood by water flow. When we write and read data, we throw data and fish data into the flow. At the beginning of learning C language, you can use printf to print characters on the screen. In fact, when using printf function, the system opens three streams by default:
Standard input stream: stdin Stream output standard: stdout Standard error flow: stderr
printf throws the data into the standard output stream, and the data will be automatically output to the screen. We can see that the function fputc is applicable to all output streams. The following program demonstrates how to use fputc to write data to standard output streams and files. Fputc can only write one character to the stream at a time.
6.5.2 file reading and writing function
this section gives some examples of file reading and writing functions for your reference. For more file reading and writing functions, please click to view: File input / output - cppreference com.
(1) Character input function fgetc
Use fgetc to read a character from the standard input stream
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> int main() { int ch = fgetc(stdin);// Use fgetc to read a character from the standard input stream printf("\n%c\n", ch);//Print the read characters to the screen return 0; }
after the program runs, wait for a character to be input, then fgetc saves the read character in ch, and prints out the read character with printf.
use fgets to read a character from a file. The following routine shows how to continuously read characters. (file input stream), when the return value of fgetc is EOF, the reading of text ends
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> int main() { FILE* pFile; pFile = fopen("myfile.txt", "r"); //Open the file as read-only. The file must exist to open successfully if (pFile == NULL)//If opening fails { perror("fopen"); return 1; } int ch = 0; //fgetc returns ASCII code, so it can be received with integer variables. In addition, it uses int type, and it also considers receiving EOF while ((ch = fgetc(pFile)) != EOF)//Read characters from the text file. When reading fails, EOF is returned { printf("%c ", ch); } fclose(pFile); pFile = NULL; //Set the pointer to null to prevent wild pointer return 0; }
(2) Character output function fputc
Write a character to the standard output stream:
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> int main() { fputc('L', stdout);// Writes a character to the standard output stream return 0; }
Using fputc to write a character to a file (file stream)
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> int main() { FILE* pFile; pFile = fopen("myfile.txt", "w"); //Open the file in write only mode. If the file does not exist, create a new file if (pFile == NULL)//If opening fails { perror("fopen"); return 1; } fputc('L', pFile);// Write a character to a file fputc('O', pFile); fputc('V', pFile); fputc('E', pFile); fclose(pFile); pFile = NULL; //Set the pointer to null to prevent wild pointer return 0; }
we open the file myfile under the project folder Txt, you can see that the data has been successfully written.
(3) Text line input function fgets
When the return value of fgets is NULL, the reading of text ends.
/*************************************** Program function: use fgets to read a line of text from the standard input stream Time: 22:06:45, May 25, 2021 Save the read data in the str character array ****************************************/ #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> int main() { char str[100] = { 0 }; fgets(str, 2, stdin); printf("%s", str);//Print the read string to the screen return 0; }
read 2 characters from the standard input stream, and the last character defaults to enter, so the final output is I.
/*************************************** Program function: use fgets to read a line of text from the file Time: 22:27:09, May 25, 2021 ****************************************/ #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> int main() { FILE* pFile; pFile = fopen("myfile.txt", "r"); //Open the file as read-only. The file must exist to open successfully if (pFile == NULL)//If opening fails { perror("fopen"); return 1; } char str[100] = { 0 }; fgets(str, 4, pFile); printf("%s", str);//Print the read string to the screen fclose(pFile); pFile = NULL; //Set the pointer to null to prevent wild pointer return 0; }
(4) Text line output function fputs
/*************************************** Program function: use fputs to write a line of text into the standard output stream Time: 22:06:45, May 25, 2021 ****************************************/ #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> int main() { fputs("I love dog.", stdout); return 0; }
/*************************************** Program function: fputs writes a line of text to a file Time: 22:12:50, May 25, 2021 ****************************************/ #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> int main() { FILE* pFile; pFile = fopen("myfile.txt", "w"); //Open the file in write only mode. If the file does not exist, create a new file if (pFile == NULL)//If opening fails { perror("fopen"); return 1; } fputs("I love dog.", pFile); fclose(pFile); pFile = NULL; //Set the pointer to null to prevent wild pointer return 0; }
(5) Format input function fscanf
fscanf formatted input statements for all input streams
/*************************************** Program function: fscanf read data from file Time: 22:51:05, May 25, 2021 ****************************************/ #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> struct S { char name[40]; int age; }; int main() { FILE* pFile; pFile = fopen("myfile.txt", "r"); //Open the file as read-only. The file must exist to open successfully if (pFile == NULL)//If opening fails { perror("fopen"); return 1; } struct S s = { 0 }; fscanf(pFile, "%s %d", s.name, &(s.age)); //Read data printf("%s %d", s.name, s.age); //Print fclose(pFile); pFile = NULL; //Set the pointer to null to prevent wild pointer return 0; }
when reading data, the type control must match the data, otherwise if the reading fails, all the subsequent ones may be read incorrectly
(6) Format output function fprintf
fprintf is a formatted output statement for all output streams
/*************************************** Program function: fprintf writes data to file Time: 22:12:50, May 25, 2021 ****************************************/ #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> struct S { char name[20]; int age; }; int main() { FILE* pFile; pFile = fopen("myfile.txt", "w"); //Open the file in write only mode. If the file does not exist, create a new file if (pFile == NULL)//If opening fails { perror("fopen"); return 1; } struct S s = { "Zhang San",20 }; fprintf(pFile, "%s %d", s.name, s.age); fclose(pFile); pFile = NULL; //Set the pointer to null to prevent wild pointer return 0; }
(7) Binary input fread
If the actual number of read data is less than the required number, the reading ends.
/*************************************** Program function: fread reads data from files in binary mode Time: 15:20:47, May 27, 2021 ****************************************/ #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> struct S { char name[20]; int age; double hight; }; int main() { FILE* pFile = fopen("myfile.txt", "rb"); //Open the file as read-only. The file must exist to open successfully if (pFile == NULL)//If opening fails { perror("fopen"); return 1; } struct S s = { 0 }; fread(&s, sizeof(s), 1, pFile); //Save data in size of binary file (read data from size of each time) printf("%s %d %lf\n", s.name, s.age, s.hight); //Print fclose(pFile); pFile = NULL; //Set the pointer to null to prevent wild pointer return 0; }
read data from the file in binary form, save the data in s, read one data at a time, and the size of each data is sizeof(s)
(8) Binary output fwrite
/*************************************** Program function: fwrite writes data to file Time: 22:12:50, May 25, 2021 ****************************************/ #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> struct S { char name[20]; int age; double hight; }; int main() { FILE* pFile = fopen("myfile.txt", "wb"); //Open the file in write only mode. If the file does not exist, create a new file (the written data is binary) if (pFile == NULL)//If opening fails { perror("fopen"); return 1; } struct S s = { "Zhang San",20,1.75 }; //Binary write fwrite( &s, sizeof(s), 1, pFile); //Write the data of s to pFile. The size of S is sizeof(s). Write 1 s in total fclose(pFile); pFile = NULL; //Set the pointer to null to prevent wild pointer return 0; }
"Zhang San" is a text. The binary form of the text is the same as the text form, so it can be understood
(9) Other read / write functions
scanf and printf are formatted input and output statements for standard input and output streams.
sscanf reads formatted data from a string. sprintf writes formatted data to a string.
getchar is also a character input function for all streams
feof function determines whether the reason for the end of file reading is the end of reading failure or the end of file (the end of file flag is EOF).