[C language] Detailed explanation of file operation

The content to be shared in this chapter is the content of file operations in C language. In order to facilitate your learning, the directory is as follows

Table of contents

1. Why use files

2. What is a file

2.1 Program files

2.2 Data files

2.3 File name

3. File opening and closing

3.1 File Pointer

 3.2 Opening and closing

4. Sequential reading and writing of files

4.1 Introduction to sequential read and write functions

4.1.1   fputc

4.1.2   fgetc

4.1.3   fputs

4.1.4    fgets

4.1.5  fprintf

4.1.6   fscanf


 

1. Why use files

When we studied the structure earlier, we wrote the address book program. When the address book is running, we can add and delete data in the address book. At this time, the data is stored in the memory. When the program exits, the address book The data in the address book will naturally disappear, and the data will have to be re-entered when the address book program is run next time. It will be very uncomfortable to use such an address book.
We are thinking that since it is an address book, the information should be recorded. Only when we choose to delete the data, the data will no longer exist.
This involves the problem of data persistence. Our general data persistence methods include storing data in disk files and storing them in databases. Using files, we can store data directly on the hard disk of the computer, achieving data persistence.

2. What is a file

My answer is that files on disk are files.

That is to say, when you turn on your computer, you will see that there are disks C and D on the computer, or some people have bought a hard disk with a larger capacity, and all the things in these hard disks can be converted into files.

But in programming, we generally talk about two kinds of files: program files and data files.

2.1 Program files

Including .c files and .cpp files when we write code, these are called source files. There are also object files (windows environment suffix .obj), executable programs (windows environment suffix .exe), that is, the files generated when we write code and run are called program files

You can simply write a code to show it

6700c440d0994a48b3e07399da010a3d.png

 Then open the file according to the file path

 1054e294f4d047db827b7c321da7b72e.png

We can see that C Source is the source file mentioned above

Then enter the Debug folder

 f46dde8a6fc94183bd518f688c05d914.png

 You can see the .exe file and .OBJ file we mentioned above, these are program files

2.2 Data files

The content of the file is not necessarily the program, but the data read and written when the program is running, such as the file from which the program needs to read data,
or the file that outputs the content.

The address book mentioned above can only be stored in the memory when it is running, and the content will be lost when it is used next time, so it must be stored and then stored as a file on the hard disk so that it can be used whenever you want. Let’s go deep below Research.

Our code will generate an .exe file when compiling, which is the result of adding, deleting, modifying and checking in the address book, so how to put it on the hard disk? Draw a picture here to show everyone

de77c46760ef4c478318ec89bc60e989.png

 If I want to store the generated program file in the hard disk, that is, store it in a .txt file, the data file is stored in this way.

  This article specifically talks about the operation of writing and reading.

Before that, there are some other things to know

2.3 File name

A file must have a unique file identifier for user identification and reference.
The file name consists of 3 parts: file path + file name trunk + file suffix
For example: c:\code\test.txt
For convenience, the file identifier is often called the file name.

How does the file work?

3. File opening and closing

Opening and closing files is like using a refrigerator. To use the items in the folder, you must first use the same as using the refrigerator. Open the refrigerator, then use the contents, and finally close the refrigerator, that is, close the folder. This operation can be read or write, and finally close the folder.

3.1 File Pointer

Seeing the word pointer, some people may think of various pointers such as array pointers and function pointers that they learned before, but in fact, file pointers are different from them. File pointers themselves are pointers of a defined type. 

In the cache file system, the key concept is "file type pointer", referred to as "file pointer".
Each used file has opened 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, named FILE.

Let's use pictures to understand

9128e9f78a3c4345b14678b9e390350b.png

 The meaning in the figure is that when we want to read or write the data.txt data file, it will actively maintain a piece of memory. This piece of memory is called the file information area. This file information is to describe this piece of data. For the file, it is used to store the information of the file, such as the name of the file, the status of the file, and the current location of the file.

Then how is this file information area stored in memory? Then use FILE to open up a space

Use FILE f to open up this section of file information area, and f can also be understood as a structure variable, and the type of this structure is FILE.

Whenever a file is opened, the system will automatically create a variable of the FILE structure according to the situation of the file and fill in the information, so the user does not need to care about the details.

Generally, the variables of this FILE structure are maintained through a FILE pointer, which is more convenient to use.

Below we can create a FILE* pointer variable:

FILE* pf;//文件指针变量


Define pf as a pointer variable pointing to FILE type data. You can make pf point to the file information area of ​​a certain file (it is a structure variable). 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.

For example, as shown below

a341c9b2dad64618bbc4ccb9941481f1.png

 3.2 Opening and closing

Files should be opened before reading and writing, and should be closed after use.
When writing a program, when opening a file, a FILE* pointer variable will be returned to point to the file, which is equivalent to establishing the
relationship between the pointer and the file.
ANSIC stipulates that the fopen function is used to open the file, and the fclose is used to close the file.

example

/打开文件
FILE * fopen ( const char * filename, const char * mode );
//关闭文件
int fclose ( FILE * stream );

Let's go to the official website to see the analysis of the two functions

9817d9794f6540e98d25abfb9552ae43.png

 You can see that there are two parameters, the first parameter means the file name, which is the name of the file you want to operate, and the second parameter is the opening method. What are the ways to open it? Depends on what you do with the file.

Open as shown below

703e83c7131a46caa675d0fac30ef65d.png

 It can be seen that there are many different ways to open

Here is a summary of several

5cd5775bf72c4f90ab65b3344ff291a3.png

 

Next, write the code by hand

 

int main()
{
	//打开文件
	FILE* pf=fopen("test.txt", "w");
	//写文件

	//关闭文件
	return 0;
}

This is a way to open a file for writing

But what we need to pay attention to is that there is no such file in my file path

c445d5d1a25d429fbf743046f64e9ac0.png

 Then you need to look at the contents of the table

48595d0120e24b078cc936fba8e4d09a.pngWhen there is no file we want to open, he will create a new file, and then we should also pay attention to the return type of the function, which is a pointer type, so we might as well

 Define a FILE * type pointer variable pf to receive. At this time, put the address of the file information area we mentioned above into pf, and pf can find the address of the file information area, and then you can find the file and operate the file. The above is to open the file operation

We can see that there will be errors in the above operation corresponding table. If the file fails to open, a null pointer will be returned, so we need to judge its return value as before.

The following code is the normal and complete operation code for opening a file

int main()
{
	//打开文件
	FILE* pf=fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件

	//关闭文件
	return 0;
}

 

Next is how to close the file

769710a145444da18724d7c6c4d41f54.png

 We can see that the return type is an integer, and the parameter only needs to pass the file pointer to it

At the same time, after we close the file, we need to avoid the use of wild pointers, so we should also turn them into null pointers.

At this time the code runs

389f7318c87b4732ad6ffcec8155ce1e.pngWe'll find the file we created in the folder 

4aa15fa3c0ba4698bccf8f7e4f14eb74.png

 It is the test.c file with a size of 0kb.

Then we change the form of writing to open in the form of reading? There is an error on the form

the code runs

b1a4609fb3d74255baa271830ae3d077.png

 You can see that when you change w to r, you can see that there is an error opening the file.

The path we mentioned above to open the test.c file is a relative path, that is, the path to operate the file in the current project area.

So what if you want to operate other files?

Here I use the files on the desktop to demonstrate

 64fae1f261ca4dd6821a4045a68fb1c6.png

 There is a test.c file on the desktop, we want to know its file path, we can right click to open her properties

fb95612e7e384a9896fdb90196b7f31f.png

At this time, we can copy his file path to the parameter of the fopen function

int main()
{
	//打开文件
	FILE* pf=fopen("C:\\Users\\19110\\Desktop\\test2.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

545b4422e4ca41eba974e5ae6cd3ce06.png

 You can see that the opening is successful (because it is empty text, so there is nothing)

When we use the write operation to open it, that is, change r to w , the system will create a new txt file on the desktop, and you can try it out.

The above is the operation of opening and closing files.

4. Sequential reading and writing of files

4.1 Introduction to sequential read and write functions

Next, share some read and write functions

0d2868c6f46b47cbb70bdcdad4e09094.png

 We can see that each function has different objects, some are for characters, some are for text lines, some are for formatting, and some are for binary. We will explain them one by one.

4.1.1   fputc

First about fputc

We can check the information about fputc on the official website

2d14644a2f4d4c32bf9f2cba31b6e09a.png

We can see that the return type of this function is integer, the first parameter is the character you want to output, and the second parameter is the file pointer, directly upload the code for everyone to use briefly

int main()
{
	//打开文件
	FILE* pf=fopen("C:\\Users\\19110\\Desktop\\test2.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	fputc('a', pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

It can be seen that we use fputc in the module for writing files, the a in the brackets is the character we want to output, and pf is the file pointer we want to operate

the code runs

20f314b5eeaa4991a05b85aebb8c526a.png

 It can be seen that it has run successfully

Then open the file in our fopen to see if a is written into the test file

badeea4d1cd04ae0aa91e9ade1e99674.png

 We can see that a is already in the test file.

If we want to enter a string, such as twenty-six should be letters, we might as well use the while loop

int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	//把二十六个英文字母写入
	int i = 0;
	for (i = 0; i < 26; i++)
	{
		fputc('a' + i, pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

Let the code go6b0b5a0ea1bc451aa5caedb8705195e5.png

 You can see that the English letters we wrote already exist in the test file.

Note (the essence of the character is the ASCII code value, so a can be added to i).

 

4.1.2   fgetc

Next is the read file operation

You can observe the official description of fgetc

6f39486c23514e65a43768c79bebaf2d.png

 It can be seen that the return type of the function is int type, and the parameter of the function is a file pointer;

0832ac37a01d4ce48a859535995eb5ec.png

The official description below is about the return value being int type: if an error occurs when reading, EOF will be returned, and the value of EOF is -1, so not only will it return the ASCII code value, but it may also return -1 , so the return type is defined as int type;

Or the above code we transform it

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	int ch = fgetc(pf);
	printf("%c\n", ch);
//关闭文件
    fclose(pf);
	pf = NULL;
	return 0;
}

 We change 'w' to 'r' to operate the file by reading. This file contains the 26 English letters we wrote.

Let the code go

a89cfea5a98c4d4da3f0b87db17de316.png

 There may be doubts here, why is the output not aaaaaaaaa...?

This is a special effect of fgetc, every time it reads a character it will move to the next one, I hope everyone can understand.

4.1.3   fputs

According to the usual practice, first observe the information on the official website

8496336b1d8f43d898c88a5d392a9f26.png

 The function has two parameters, the first parameter is a string, the second parameter is a file, and the return type is an integer type of data

Use the code to simply understand his use

int main()
{
	//读文件
	FILE* pf = fopen("text", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写数据
	fputs("hello world",pf);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

The code runs and observes

6543821475e84c0bb6b3583755edcf55.png

We see that the write has been successful 

What if we write one more time below?

a89e2e0e85f44ed184c3bcb93f35e0ed.png

 operation result

38d816aaea344a10ab2a26c19fbbe03a.png

 When we open this file again to check whether they have been written, you will find that they appear on the same line. It is very simple to want them to appear on two lines, just add \n at the end

855e455855904153ba9640cbeef79ae8.png

 should not be difficult to understand 

4.1.4    fgets

Still first observe the official description

56c1cd37cac24c9b982557e6bb776488.png

 You can see that the return type of the function is the pointer type of char*, and there are three parameters. The content of his parameters is also introduced below

11f1ba83371c456cb3ef5da3ae803570.png

 

The first parameter means to copy the string of the file in the third parameter to the first parameter;

The second parameter means how many characters to copy at most to the first parameter (note that '\0' is also a character, so write one more number than the string you want to copy);

The third parameter is the file to be operated on

Continue to use the code simply, or operate on the file we just created;

int main()
{
	//打开文件
	FILE* pf = fopen("text", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读数据
	char arr[20];
	fgets(arr, 5, pf);
	printf("%s\n", arr);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

operation result

 

ce44e946c9234bd3b62f022353417352.png

 You can see that you want to copy 5 characters in the function, but there are only four characters in the output result. This function puts '\0' at the end

should not be difficult to understand

4.1.5  fprintf

First observe the official description of it

fprintf first

b0f3c8b26edf497db87a100111f657fe.png

 Some people may be confused when seeing this parameter, so we might as well compare the printf we have learned

0c2f0487b99b437999ca0638caa269cf.png

 You will find that the parameter is just one more file pointer

0c960d2256d24449a53fb8c8d6bf6d6c.png

 

Then when using it, we only need to add one more parameter to printf

 Below is the simple code to use

struct S
{
	int n;
	float f;
	char arr[20];
};
int main()
{
	struct S s = {100,3.14f,"zhangsan"};
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	fprintf(pf,"%d %f %s", s.n, s.f, s.arr);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

run up

8b01a4aa24564e79b5c55fe686a6583d.png

We will find that it has been written in the corresponding file 

4.1.6   fscanf

97fedc305e664c0ba3fb624536934b6a.png

 Compare it to the scanf we have learned first

ef0f17d94e7e4b03b021fc520bb0af65.png

 It can be seen that there is still only one more function to operate the file. 

Then we use code to make it simple and practical

struct S
{
	int n;
	float f;
	char arr[20];
};
int main()
{
	struct S s = { 0 };
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	fscanf(pf,"%d %f %s", &(s.n), &(s.f), s.arr);
	printf("%d %f %s", s.n, s.f, s.arr);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

It can be seen that we initialize the content of the structure to 0 at the very beginning, because we need to use the function to read the content of the file itself, which is the file we wrote with fprintf above.

After we read successfully, we will print out the content we read

Let the code run

aff4d5dcde6a4405af3e7bfa9d489587.png

 You can see that all the information in this file has been read out.

The above is what I want to share this time. If it is helpful to you, you may wish to support it three times. Thank you for reading.

 

 

Guess you like

Origin blog.csdn.net/wangduduniubi/article/details/129826801