C language file operation details

Keywords: C Algorithm

preface

In C language, file is an important concept in programming. The operating system manages data in the unit of files. Although there may not be many places to use files in the future, files are still an indispensable part of C language. Well, no more nonsense. Let's get straight to the point.

1, What is a file

Concept: files on disk are files.

But in programming, we generally read two kinds of files: program file and data file.

Procedure documents:

It includes source program files (suffix. c), object files (suffix. obj in windows Environment), and executable programs (suffix. exe in windows Environment).

Data file:

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

Today we are talking about data files.

Before that, the input and output of data we processed were targeted at the terminal, that is, input data from the keyboard of the terminal and display the operation results on the display.

In fact, sometimes we will output information to the disk, and then read the data from the disk to the memory when necessary. What we deal with here is the files on the disk.

2, File name

A file should have a unique file ID to enable users to identify and reference.

The file name consists of three parts: file path + file name trunk + file suffix
For example:

c:\code\test.txt

For convenience, the file ID is often referred to as the file name.

3, File type

According to the organization form of data, data files are called text files or binary files.

Data is stored in binary form in memory. If it is output to external memory without conversion, it is a binary file.

If it is required to store in the form of ASC Ⅱ code on external memory, it needs to be converted before storage. The file stored in the form of ASC Ⅱ characters is a text file.

So how is a data stored in memory?
All characters are stored in ASC Ⅱ form, and numerical data can be stored in ASC Ⅱ form or binary form.

If there is an integer of 10000:

1. Text description

If it is output to the disk in the form of ASC Ⅱ code, the disk occupies 5 bytes (each character occupies one byte),
The binary output only takes up 4 bytes on the disk (10000 is an integer without any conversion, so it takes up 4 bytes).

2. Image interpretation

3. Code interpretation

Example 1:

#include<stdio.h>
int main()
{
	int a = 10000;
	FILE* pf = fopen("test.txt", "wb");// fopen: create    
	//"WB" -> write binary is written in binary form 
	fwrite(&a, 4, 1, pf);// Write to file in binary form
	fclose(pf);// Close file 
	pf = NULL;
	return 0;
}

Through such a code, we can see that such a file appears under the folder:

If we open it directly, there is the so-called garbled code inside, and we can't understand it, how can we understand it?
The compiler used by bloggers here is: Visual Studio 2019

① First add the test.txt file to the project:

② Select open mode - > binary mode:


③ Open the file test.txt:

What we see is: 10 27 00 00. If we want to read in memory, we should read in reverse order, because this is small end storage, and get: 00 00 27 10

Then we find that the hexadecimal number is converted to decimal, which is exactly 10000

4, File buffer

ANSIC standard adopts "buffer file system" to process data files. The so-called buffer file system refers to that the system automatically opens up a "file buffer" for each file in use in the program in memory.

Data output from memory to disk will be sent to the buffer in memory first, and then sent to disk together after the buffer is filled.

If you read data from the disk to the computer, read the data from the disk file, input it into the memory buffer (fill the buffer), and then send the data from the buffer to the program data area (program variables, etc.) one by one.

The size of the buffer is determined according to the C compilation system.

The diagram is as follows:

5, File 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.). This information is stored in a structure variable. The structure type is declared by the system and named FILE.

You can view the definition of the FILE structure in the header FILE of studio. H (located in the include folder under the visual studio installation directory), as follows:

struct _iobuf {  
        char *_ptr;  
        int   _cnt;  
        char *_base;  
        int   _flag;  
        int   _file;  
        int   _charbuf;  
        int   _bufsiz;  
        char *_tmpfname;  
        };  
typedef struct _iobuf FILE; 

The FILE types of different compilers contain different contents, but they are similar.

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 the 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

PF is defined as a pointer variable pointing to FILE type data, which can make pf point to a FILE information area (a structure variable). The FILE can be accessed through the information in the FILE information area. That is, the FILE associated with it can be found through the FILE pointer variable.

As shown in the figure:

6, Opening and closing of files

The file should be opened before reading and writing, and closed after use.

When writing a 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.

ANSIC specifies that fopen function is used to open the file and fclose function is used to close the file.

	FILE * fopen ( const char * filename, const char * node);
	int fclose ( FILE * stream );

The opening method is as follows:

How files are usedmeaningIf the specified file does not exist
"r" (read only)To enter data, open an existing text fileerror
"w" (write only)To output data, open a text fileCreate a new file
"a" (added)Add data to the end of a text fileerror
"rb" (read only)To enter data, open a binary fileerror
"wb" (write only)To output data, open a binary fileCreate a new file
"ab" (additional)Add data to the end of a binary fileerror
"r +" (read / write)To read and write, open a text fileerror
"w +" (read / write)Create a new file for reading and writingCreate a new file
"a +" (read / write)Open a file and read and write at the end of the fileCreate a new file
"rb +" (read / write)To read and write, open a binary fileerror
"wb +" (read / write)Create a new binary file for reading and writingCreate a new file
"ab +" (read / write)Open a binary file and read and write at the end of the fileCreate a new file

1. Opening of files

(1) Code example

Example 2: open the test.txt file

#include<stdio.h>
int main()
{
	// Open the file test.txt
	// fopen("test.txt", "r");
	
	// Equal path:
	//  .. Indicates the upper level path
	//  . indicates the current path
	// fopen("..\\test.txt","r");
	
	// Absolute path:
	// fopen("D:\c language \ \ file operation explanation \ \ file operation explanation \ \ test.txt", "r");
	// The symbol "\" may be escaped, so it takes the form of "\ \"

	FILE* pf = fopen("test.txt", "r");

	return 0;
}

(2) Illustration

(3) Error prone point

Similarly, the opening of a FILE may fail. When the opening fails, pf this pointer is NULL and the FILE structure is not created successfully. Therefore, we should judge whether the opening is successful.

for instance
Example 3:

#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		// Print error reason
		printf("%s\n", strerror(errno));
		// strerror -> #include<string.h>
		// errno -> #include<errno.h>
		return 0;
	}
	return 0;
}

Here we use strerror(errno) to print errors.

2. File closing

(1) Code example

Example 4:

#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		// Print error reason
		printf("%s\n", strerror(errno));
		// strerror -> #include<string.h>
		// errno -> #include<errno.h>
		return 0;
	}
	else
	{
		// Open successfully
		fputs("fopen example", pf);
		// read file
		// Close file
		fclose(pf);
		pf = NULL;
	}
	
	return 0;
}

The operation result is:
(successful) (when file exists)
No such file or directory

(2) Error prone point

For example 4: when fclose closes a file, it actually frees up the space in the file information area of the file, similar to the free function, but the pointer pf is not set to 0, so there is a risk.

So, for code

	fclose(pf);
	pf = NULL;

Be sure to use it together.

7, Sequential reading and writing of files

functionFunction nameApply to
Character input functionfgetcAll input streams
Character output functionfputcAll output streams
Text line input functionfgetsAll input streams
Text line output functionfputsAll output streams
Format input functionfscanfAll input streams
Format output functionfprintfAll output streams
Binary inputfreadfile
Binary outputfwritefile

1. About flow

Our usual operations are input and output from the keyboard to the screen, and the keyboard and screen here are external devices.

Keyboard - standard input device - stdin
Screen - standard output device - stdout
It is a program that opens two streaming devices by default

When the program runs, three streaming devices are opened by default:

stdin (type) - > file*
stdout (type) - > file*
stderr (type) - > file*

2. fputc function (write file)

Now that we have learned to create files and open files, how do we write files?

C language gives us a function: fputc to complete the operation of writing files. Its general form is as follows:

	int fputc (int c, FILE *fp);

The operation is as follows:
Example 5:

#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
	FILE* pfWrite = fopen("test.txt", "w");
	if (pfWrite == NULL)
	{
		// Print error reason
		printf("%s\n", strerror(errno));
		// strerror -> #include<string.h>
		// errno -> #include<errno.h>
		return 0;
	}
	// Write file
	fputc('x', pfWrite);
	fputc('i', pfWrite);
	fputc('y', pfWrite);
	fputc('o', pfWrite);
	fputc('u', pfWrite);

	// Close file
	fclose(pfWrite);
	pfWrite = NULL;

	return 0;
}

Through example 5, we write "xiyou" into the file test.txt. Because the file test.txt did not exist before, when using "w", we will create a new file named "test.txt" and then write "xiyou".

When you open this file with Notepad, you will see the following:

In this way, we have completed a simple write file.

3. fgetc function (read file)

We have just learned how to write a file. After writing the file, how do we read it?

C language also gives us a function: fgetc to complete file reading. Its general form is as follows:

	int fgetc(FILE *stream);

The operation is as follows:
Example 6:

#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
	FILE* pfRead = fopen("test.txt", "r");
	if (pfRead == NULL)
	{
		// Print error reason
		printf("%s\n", strerror(errno));
		// strerror -> #include<string.h>
		// errno -> #include<errno.h>
		return 0;
	}
	// read file
	printf("%c", fgetc(pfRead));
	printf("%c", fgetc(pfRead));
	printf("%c", fgetc(pfRead));
	printf("%c", fgetc(pfRead));
	printf("%c", fgetc(pfRead));

	// Close file
	fclose(pfRead);
	pfRead = NULL;

	return 0;
}

The running result is: xiyou

When reading a file, use fgetc(pfRead) multiple times without + 1. It defaults to the next bit.

4. Standard I / O streams for fgetc and fputc

Example 7:

#include<stdio.h>
int main()
{
	int a = fgetc(stdin);
	// Read information from standard input stream
	fputc(a, stdout);
	// Writes information to the standard output stream

	return 0;
}

When we enter: h
The operation result is: h

Example 7 achieves a result of reading information from the keyboard and outputting it to the screen.

We have also used fgetc and fputc before. At that time, we input and output to the file, so these two functions are applicable to all input streams and output streams respectively.

5. fputs function (write file)

It is true that you can input files using the fputc function, but you can only write one character at a time. Can we write more?

C language provides us with fputs function to input text lines. Its general form is as follows:

	int fputs(const char *str, FILE *stream);

Let's take an example:
Example 8:

#include<stdio.h>
int main()
{
	char buf[1024] = { 0 };

	FILE* pfWrite = fopen("test.txt", "w");
	if (pfWrite == NULL)
	{
		return 0;
	}
	// Write file
	fputs("hello", pfWrite);
	fputs("world", pfWrite);

	// Close file
	fclose(pfWrite);
	pfWrite = NULL;

	return 0;
}

Open the file test.txt with Notepad, as shown in the figure:

Some people will have questions about why there is no line break here. This is because we directly enter hello and world, which do not have "\ n". If we need line break, we need to add "\ n" ourselves.

6. fgets function (read file)

The fgetc function can indeed read files, but it can only read one character at a time. Can we read more?

C language provides us with fgets function to read text lines. Its general form is as follows:

	char *fgets(char *str, int n, FILE *stream);

It is still the test.txt file. We open it with notepad and add hello, as shown in the figure:

Then read the text line:
Example 9:

#include<stdio.h>
int main()
{
	char buf[1024] = { 0 };
	
	FILE* pfRead = fopen("test.txt", "r");
	if (pfRead == NULL)
	{
		return 0;
	}
	// read file
	fgets(buf, 1024, pfRead);
	printf("%s", buf);
	
	fgets(buf, 1024, pfRead);
	printf("%s", buf);

	// Close file
	fclose(pfRead);
	pfRead = NULL;

	return 0;
}

The operation result is:
hello
xiyou

be careful:
① When the "fgets(buf, 1024, pfRead);" operation here is used multiple times, like the fgetc function, it will automatically + 1 and read the next line.
② The code in the text is actually like this:

hello\n
xiyou\n

We also read "\ n" into buf when reading, so there is no need to wrap when printing.

7. Standard I / O streams for fgets and fputs

Example 10:

#include<stdio.h>
int main()
{
	// Read a line of text information from the keyboard
	char buf[1024] = { 0 };

	fgets(buf, 1024, stdin);// Read from standard input stream
	fputs(buf, stdout);// Output to standard output stream

	return 0;
}

When we enter: Hello World
The running result is helloworld

8. fprintf function (write file)

Only using fgetc and fgets functions is not enough to solve practical problems. When we encounter problems such as structures, we need to format them.

C language provides us with fprintf function to format the output. Its general form is as follows:

	int fprintf (FILE* stream, const char*format[,argument] ...)

For example:
Example 11:

#include<stdio.h>
struct S
{
	int n;
	float score;
	char arr[10];
};
int main()
{
	struct S s = { 1,99.5f,"xiyou" };

	FILE* pfWrite = fopen("test.txt", "w");
	if (pfWrite == NULL)
	{
		return 0;
	}
	// Write files in formatted form
	fprintf(pfWrite, "%d %f %s", s.n, s.score, s.arr);

	// Close file
	fclose(pfWrite);
	pfWrite = NULL;

	return 0;
}

Open the file test.txt with Notepad, as shown in the figure:

9. fscanf function (read file)

Only using fputc and fputs functions is not enough to solve practical problems. When we encounter problems such as structures, we need to format them.

C language provides us with fscanf function to format input. Its general form is as follows:

	int fscanf(FILE *stream, char *format[,argument ...]);

For example:
Example 12:

#include<stdio.h>
struct S
{
	int n;
	float score;
	char arr[10];
};
int main()
{
	struct S s = { 0 };

	FILE* pfRead = fopen("test.txt", "r");
	if (pfRead == NULL)
	{
		return 0;
	}
	// Input file in formatted form
	fscanf(pfRead, "%d %f %s", &(s.n), &(s.score), s.arr);
	printf("%d %f %s\n", s.n, s.score, s.arr);

	// Close file
	fclose(pfRead);
	pfRead = NULL;

	return 0;
}

The running result is 1 99.500000 xiyou

10. Standard I / O streams for fscanf and fprintf

Example 13:

#include<stdio.h>
struct S
{
	int n;
	float score;
	char arr[10];
};
int main()
{
	struct S s = { 0 };

	fscanf(stdin, "%d %f %s", &(s.n), &(s.score), s.arr);
	fprintf(stdout, "%d %f %s", s.n, s.score, s.arr);

	return 0;
}

When we enter: 1 99.5 xiyou
The running result is 1 99.500000 xiyou

11. Make a comparison

scanf/printf

Is a formatted input / output statement for a standard input stream / standard output stream

fscanf/fprintf

Is a formatted input / output statement for all input streams / all output streams

sscanf/sprintf

sscanf reads formatted data from a string
sprintf is to output (store) formatted data into a string

(1) sprintf function

Function: write formatted data into a string
General form:

	int sprintf(char *string, char *format [,argument,...]);

for instance:
Example 14:

#include<stdio.h>
struct S
{
	int n;
	float score;
	char arr[10];
};
int main()
{
	struct S s = { 1,99.5f,"xiyou" };
	char buf[1024] = { 0 };
	// Convert the formatted data into a string and store it in buf
	sprintf(buf, "%d %f %s", s.n, s.score, s.arr);
	printf("%s\n", buf);

	return 0;
}

The running result is 1 99.500000 xiyou

**Note: * * the result here is in string form!

(2) sscanf function

Function: read the data in the formatted string.
General form:

	int sscanf(char *buffer, char *format [,argument....]); 

for instance:
Example 15:

#include<stdio.h>
struct S
{
	int n;
	float score;
	char arr[10];
};
int main()
{
	struct S s = { 1,99.5f,"xiyou" };
	struct S tmp = { 0 };
	char buf[1024] = { 0 };
	// Convert the formatted data into a string and store it in buf
	sprintf(buf, "%d %f %s", s.n, s.score, s.arr);
	// Read formatted data from buf to tmp
	sscanf(buf, "%d %f %s", &(tmp.n), &(tmp.score), tmp.arr);
	printf("%d %f %s\n", tmp.n, tmp.score, tmp.arr);

	return 0;
}

The running result is 1 99.500000 xiyou

8, Random reading and writing of files

1. fseek function

Locate the file pointer according to the position and offset of the file pointer

Its general form is:

	int fseek(FILE *stream, long offset, int origin);

The first parameter stream is the file pointer
The second parameter offset is the offset. A positive number indicates a positive offset and a negative number indicates a negative offset
The third parameter origin sets where to start the offset from the file. The possible values are:
SEEK_CUR, SEEK_END or SEEK_SET
SEEK_SET: beginning of file
SEEK_CUR: current position
SEEK_END: end of file

Let's take an example
Example 16:

#include<stdio.h>
int main()
{
	FILE* pfWrite = fopen("test.txt", "w");
	if (pfWrite == NULL)
	{
		return 0;
	}
	// 1. Write file
	fputs("welcome to xiyou", pfWrite);

	// Close file
	fclose(pfWrite);
	pfWrite = NULL;

	FILE* pfRead = fopen("test.txt", "r");
	if (pfRead == NULL)
	{
		return 0;
	}
	// 2. Locate file pointer
	fseek(pfRead, 2, SEEK_CUR);

	// 3. Read file
	int ch = fgetc(pfRead);
	printf("%c\n", ch);

	// Close file
	fclose(pfRead);
	pfRead = NULL;
	return 0;
}

The operation result is: l

Analysis: first, we use pfWrite to write the file, use the fgets function we learned before, and write "welcome to xiyou"; Then we use pfRead to read the file. First, we locate the file pointer through fseek. The current position is the starting position, i.e. "w", and the offset is 2, so we locate it to "l", then write the current character through fgetc we learned before, and finally print the read result of fgetc through the variable ch.
Note: when setting the offset of fseek() function, be careful not to exceed the range of the file!

2. ftell function

Returns the offset of the file pointer from the starting position

Its general form is:

	long int ftell(FILE *stream);

Let's take an example:
Example 17:

#include<stdio.h>
int main()
{
	FILE* pfWrite = fopen("test.txt", "w");
	if (pfWrite == NULL)
	{
		return 0;
	}
	// 1. Write file
	fputs("welcome to xiyou", pfWrite);

	// Close file
	fclose(pfWrite);
	pfWrite = NULL;

	FILE* pfRead = fopen("test.txt", "r");
	if (pfRead == NULL)
	{
		return 0;
	}
	// 2. Locate file pointer
	fseek(pfRead, -2, SEEK_END);

	int pos = ftell(pfRead);
	printf("%d\n", pos);

	// Close file
	fclose(pfRead);
	pfRead = NULL;
	return 0;
}

The operation result is: 14

Analysis: first, we use pfWrite to write the file, use the fgets function we learned before, and write "welcome to xiyou"; Then we use pfRead to read the file, locate the file pointer through fseek, the end of the file is "o", the offset is - 2, and locate it to "y", and then use ftell function, its return value is "the offset of the file pointer from the starting position", which is also shaping, so print with the variable pos, and the offset of "y" from "w" is 14, so 14 is returned.

3. rewind function

Returns the position of the file pointer to the starting position of the file

Its general form is:

	void rewind(FILE *stream);

Let's take an example:
Example 18:

#include<stdio.h>
int main()
{
	FILE* pfWrite = fopen("test.txt", "w");
	if (pfWrite == NULL)
	{
		return 0;
	}
	// 1. Write file
	fputs("welcome to xiyou", pfWrite);

	// Close file
	fclose(pfWrite);
	pfWrite = NULL;

	FILE* pfRead = fopen("test.txt", "r");
	if (pfRead == NULL)
	{
		return 0;
	}
	// 2. Locate file pointer
	fseek(pfRead, 9, SEEK_CUR);

	// Print
	int ch = fgetc(pfRead);
	printf("%c\n", ch);

	// Return to starting position
	rewind(pfRead);
	
	// Print
	ch = fgetc(pfRead);
	printf("%c\n", ch);

	// Close file
	fclose(pfRead);
	pfRead = NULL;
	return 0;
}

The operation result is:
o
w

Analysis: we first locate "o", read the print, and then use the rewind function to read the print again. It is found that the result of the second print is "w", indicating that rewind makes the current position of the file pointer the starting position.

9, Determination of end of document

1. How to print errors

(1) strerror function

In the dynamic memory allocation module, we learned the strerror function to the string address of the error information corresponding to the error code.

For example:
Example 19:

#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
	FILE* pfRead = fopen("test2.txt", "r");
	if (pfRead == NULL)
	{
		// Print error reason
		printf("%s\n", strerror(errno));
		// strerror -> #include<string.h>
		// errno -> #include<errno.h>
		return 0;
	}

	// Close file
	fclose(pfRead);
	pfRead = NULL;
	return 0;
}

The operation result is:
No such file or directory

Analysis: the file "test2.txt" does not exist here, but we use "r" to read it. As mentioned earlier, this will report an error,

(2) perror function

Today we're going to learn another way to print errors - the perror function
Its general form is:

	void perror(const char *str)

The use of the perror function is very simple. It does not need to reference so many header files like the strerror function. It is contained in "stdio.h", and it does not need to pass an error code.

The output form of perror function is:

str: error reason

Let's take an example:
Example 20:

#include<stdio.h>
int main()
{
	FILE* pfRead = fopen("test2.txt", "r");
	if (pfRead == NULL)
	{
		perror("File opening failed");
		return 0;
	}

	// Close file
	fclose(pfRead);
	pfRead = NULL;
	return 0;
}

The operation result is:
File opening failed: No such file or directory

2. feof function

Detect the file terminator on the stream. If the file ends, a non-0 value is returned; otherwise, 0 is returned

Its general form is:

	int feof(FILE *stream);

(1) Text file

Take an example
Example 21:

#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("File opening failed");
		return 0;
	}
	// read file
	int ch;
	// Note: int, not char, requires EOF processing

	// fgetc will return EOF when reading fails or when the file ends
	while ((ch = fgetc(pf)) != EOF) // Standard C I/O read file cycle
	{
		putchar(ch);
	}

	printf("\n");

	//Judge why it ended
	if (ferror(pf))
	{
		printf("I/O error when reading\n");
	}
	else if (feof(pf))
	{
		printf("End of file reached successfully\n");
	}

	// Close file
	fclose(pf);
	pf = NULL;
	return 0;
}

The operation result is:
welcome to xiyou
End of file reached successfully

(2) Binary file

Let's take an example
Example 22:

#include<stdio.h>
enum {
	SIZE = 5
};
int main()
{
	double a[SIZE] = { 1.0,2.0,3.0,4.0,5.0 };
	double b = 0.0;
	size_t ret_code = 0;
	FILE* pf = fopen("test.bin", "wb"); // wb - binary form
	if (pf == NULL)
	{
		perror("File opening failed");
		return 0;
	}
	// Write an array of double
	fwrite(a, sizeof(*a), SIZE, pf);
	fclose(pf);

	pf = fopen("test.bin", "rb"); // rb - binary form
	// Read array of double
	while ((ret_code = fread(&b, sizeof(double), 1, pf)) >= 1)
	{
		printf("%lf\n", b);
	}

	//Judge why it ended
	if (ferror(pf))
	{
		printf("Error reading test.bin\n");
	}
	else if (feof(pf))
	{
		printf("Error reading test.bin: unexpected end of file\n");
	}

	// Close file
	fclose(pf);
	pf = NULL;
	return 0;
}

The operation result is:
1.000000
2.000000
3.000000
4.000000
5.000000
Error reading test.bin: unexpected end of file

(3) Summary of error prone points

Misused feof

Note: during text reading, the return value of the feof function cannot be directly used to judge whether the file is finished! It is used to judge whether the reading fails or the end of the file is encountered when the file reading ends.

① Whether the text file reading is completed, and judge whether the return value is EOF (fgetc) or NULL (fgets)
For example:
I. fgetc determines whether the return value is EOF.
II. fgets determines whether the return value is NULL.

② Judge whether the return value is less than the actual number to be read.
For example:
fread determines whether the return value is less than the actual number to be read.

summary

This is the end of the relevant knowledge about file operation. There are still many concepts. We need to study hard. We must not be eager for quick success and instant benefits. We need to learn step by step. I believe everyone who can see here is certainly willing to do so. See you in the next issue. Come on!

Posted by Tjeuten on Sat, 27 Nov 2021 21:25:53 -0800