C language file related operation notes

The file is a form of saving on the hard disk.

File = file attribute + file content The
file attribute is also data (such as modification date, size, type)

The knowledge of things is generally based on attributes.

The value of the file path: positioning (easy to find)

File name: Determine the specified file under a certain path

File name = file trunk + file suffix

Operations on files generally include two parts: operations on content and operations on attributes

In program design, generally speaking, there are two kinds of files: program files, data files.
Program files: including source files (suffix .c files), target files (.obj files for windows, .o files for Linux), executable programs (Windows is .exe).
Data file: The content of the file is not necessarily data, but the data read and written when the program is running, such as a file that needs to read data from the program to run, or a file that outputs content.

File type: According to the organization of data, data files are called binary files and text files .
Binary file: The data is stored in the memory in binary form, and stored in the file intact without conversion.
Text file: A file stored in the form of ASC II characters.

int main()
{
	int a = 10000;
	FILE *fp = fopen("test.txt", "wb");
	if (fp == NULL)
	{
		return 1;
	}
	fwrite(&a, 4, 1, fp);
	fclose(fp);
	return 0;
}

Write a to the file in binary form, and open the file as garbled characters.
Insert picture description here
If you want to store a text file, just define a character variable.

int main()
{
	int a = 10000;
	FILE *fp = fopen("test.txt", "wb");
	if (fp == NULL)
	{
		return 1;
	}
	const char *str = "10000";
	fwrite(str, 4, 1, fp);
	fclose(fp);
	return 0;
}

Open the test file:
Insert picture description here

 
 
 
File buffer:

int main()
{
	printf("Hello world!");
	Sleep(3);
	return 0;
}

In the current situation: the code runs from top to bottom, regardless of whether it is carried or not “\n”, printf is executed first.
In the Linux operating system, we can see that the output will not be printed immediately, but will pause for 3 seconds and print it out after the program ends.

Why is this happening?
This is because there is a buffer when the program is running. When outputting to the hard disk or the display, the data is first in the buffer. If there is a refresh method, it will be refreshed immediately. If not, it will be refreshed when the buffer is full, or When the program ends, it will refresh automatically, or refresh it actively.

In this example, printf writes to the buffer first, and when appropriate (\n, active refresh, program exit) to the display.

“\n”When printing to the display, the refresh strategy adopted is line refresh. When there is no'\n', there is no refresh, the data is in the buffer, and it will refresh after sleep.

 
When the C program is started, three files are opened by default: standard input, standard output, and standard error.
The corresponding hardware devices are: keyboard, monitor, and monitor.
The corresponding FILE * are called: stdin, stdout, sdterr

You can take an active refresh strategy. fflush(stdout), it can be refreshed.

Insert picture description here

Under normal circumstances, you can either directly transmit the data to the display, or put the data in the buffer, and then transmit the data to the display.

But this operation is rarely done. Generally, the data is put into the buffer first, and printf puts the data into the buffer. The operation between memory -> memory is very fast, and memory -> external memory is very slow.

What is a buffer?
It is a memory area.

Why should there be a buffer? (The value of the buffer?)
Improve the efficiency of the program.

for example:

You want to send things to your friends far away, and you personally send them to your friends. It takes time and money along the way, causing a lot of waste.
At this time, you hand over the items to the courier company for a certain fee, and let the courier company deliver the items for you, and you can do your own things, just wait for the items to arrive. -by egg brother

In this example, things (Hello word), you (printf), courier company (buffer). If you give something to the courier company, it is equivalent to the program putting Hello world in the buffer, and the program can continue to execute, if there is a refresh, refresh it. And you can also do your own things to improve efficiency.

 
Three buffering methods:

  1. Unbuffered: no buffer
  2. Line buffering: the buffer size is only one line, and it will be refreshed when it is full (displays mostly use this)
  3. Full buffer: refresh the buffer when the buffer is full (hard disk)

 
 
File pointer : Each opened file has a corresponding file information area in the memory, which is used to store the related information of the file (file name, file location, etc.). This information is stored in a structure variable whose declaration is FILE .

Define a FILE *, make the pointer point to the information area of ​​a file, and then operate the file through the pointer.

File opening:

FILE * fopen(const char *filename,const char *mode)

The name of the opened file and the method of opening.
After opening, it is necessary to judge whether the file is successfully opened, otherwise it is not known whether the file is opened successfully.

Closing of the file:

int fclose(FILE *stream);

After the file operation is completed, the file should be closed.

File opening method:
Insert picture description here
sequential reading and writing of files:

  1. fgetc : int fgetc ( FILE * stream );Character input function, read every character in the file sequentially. -1 is returned when the file is read. If the file is read incorrectly, -1 will be returned, but an error will be set (ferror)
  2. fputc : int fputc ( int character, FILE * stream );Character output function, write characters to the file sequentially, write successfully, return the character, write error, return EOF, and set error (ferror)
  3. fgets : char * fgets ( char * str, int num, FILE * stream );text line input function, read num characters of the file, into the string, the capacity of the string should be large enough. The string is returned successfully.
  4. fputs :, int fputs ( const char * str, FILE * stream );text line output function, write all strings into the file. Return a non-negative value successfully.
  5. fscanf :, int fscanf ( FILE * stream, const char * format, ... );format the input function, read the data in the file into the corresponding variable, need to explain the specific data type.
  6. fprintf :, int fprintf ( FILE * stream, const char * format, ... );format the output function, write data to the corresponding file, pay attention to the type of data. If successful, return the data length written
  7. fread : size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );Binary input function, read the file into the data in binary mode, size is the number of bytes read, count is how many such bytes are read. Reading is successful, return the value of count.
  8. fwrite : size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );Binary output function, write data to the file in binary form. The write is successful, and the count value is returned.

 
 
Random reading and writing of files:

  1. fseek : int fseek ( FILE * stream, long int offset, int origin );locate the file pointer according to the position and offset of the file pointer.
    E.g:
int main()
{
	FILE *fp = fopen("test.txt", "wb");
	char str[15] = "i like you";
	fwrite(str, 5, 2, fp);
	int a = fseek(fp,2,SEEK_SET);
	fputs("love you", fp);
	printf("%s\n", strerror(errno));
	printf("%s", str);
	printf("%d", a);
	return 0;
}

Change the position of the current file pointer and modify the following data.
SEEK_SET Start of file
SEEK_END End of file SEEK_CUR
Current position

  1. ftell : long int ftell ( FILE * stream );Return the offset of the file pointer relative to the starting position.
    E.g:
	FILE *fp = fopen("test.txt", "rb");
	if (fp == NULL)
	{
		return 1;
	}
	long size;
	fseek(fp, 0, SEEK_END);
	size = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	printf("%d\n", size);

Use the fseek function to make the file pointer point to the end, and then use the ftell function to find the offset between the two. Finally, point the file pointer to the starting position.

3. rewind :, void rewind ( FILE * stream );let the file pointer point back to the beginning of the file.
Just like the above example, just use it directly.

 
 
 
This section can give a practical example, we can copy a file and use the above function.
Join us to copy a picture, which can be achieved by opening the sample file first, then opening the file to be copied, finding the number of bytes in the sample file, and then copying it.

int main()
{
	FILE *sample = fopen("sample.jpg", "rb");
	if (sample == NULL)
	{
		return 1;
	}
	FILE *copysample = fopen("copysample.jpg", "wb");
	if (copysample == NULL)
	{
		return 2;
	}
	fseek(sample, 0, SEEK_END);
	long size = ftell(sample);
	rewind(sample);
	char *temp = (char *)malloc(size);
	if (temp == NULL)
	{
		return 3;
	}
	fread(temp, size, 1, sample);
	fwrite(temp, size, 1, copysample);
	fclose(sample);
	fclose(copysample);
	free(temp);
	return 0;
}

Files copied:
Insert picture description here

These three functions operate on file attributes.

 
 
 
 
End of file judgment:

In the process of file reading, feofthe return value of the function cannot be used directly to determine whether the file is over. Rather, it is used when the file reading ends to determine whether the reading fails or the end of the file is encountered.

  1. Whether the text file reading is over, judge whether the return value is EOF (fgetc) or NULL (fgets)

fgetc judges whether it is EOF
fgets judges whether it is NULL

  1. Judgment of the end of reading the binary file, and judge whether the return value is less than the actual number to be read.

fread determines whether the return value is less than the actual number to be read

E.g:

size_t ret=0
while ((ret = fread(temp, sizeof(temp), 1, fp)) >= 1)

 
 

 

 
Summary: In this area, it is mainly necessary to perform proficient operations on functions, random read and write of files, use more, file end judgment, distinguish binary files and text files, their end judgments are different, and deepen the buffering Understanding of the district.

Guess you like

Origin blog.csdn.net/w903414/article/details/107311438