[C language] file operation

preface

When we write a piece of code to process the data, the data is stored in memory. When the program exits, the data does not exist. When the program runs next time, the data must be re entered, which involves the problem of data persistence. The general methods of data persistence include storing the data in disk files Stored in the database.
Using files, we can store the data directly on the hard disk of the computer, so as to achieve the persistence of the data.

1, Documents

Files on disk are files. But in programming, we generally talk about two kinds of files: program files and data files (classified from the perspective of file function).

1. Procedure documents

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

2. Data files

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.

3. File name

A file should have a unique file ID so that users can identify and reference it.
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.

2, Opening and closing of files

1. 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.
Generally, the variables of the FILE structure are maintained through a FILE pointer, which is more convenient to use. For example:

FILE* pf;//File pointer variable

Definition PF is a pointer variable to data of type FILE. You can make pf point to the FILE information area (a structure variable) of a FILE. 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.

2. 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 is used to close the file.

For example:

#include <stdio.h>
int main()
{
	//Open file
	FILE* pf = fopen("data.txt", "r");//Open file, read only
	if (pf == NULL)
	{
		perror("fopen");//Print out the reason why opening the file failed
		return -1;
	}
	//read file

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

When opening the file again, you must judge whether the file is empty, and then remember to close the file after the file operation is completed.

Opening method:

File usagemeaningIf the specified file does not exist
"r" (read only)To enter data, open an existing text file error
"w" (write only)To output data, open a text file Create a new file
"a" (added) Add data to the end of a text file Create a new file
"rb" (read only)To enter data, open a binary file error
"wb" (write only)To output data, open a binary file Create a new file
"ab" (additional) Add data to the end of a binary file error
"r +" (read / write)To read and write, open a text file error
"w +" (read / write)A new file is recommended for reading and writing Create a new file
"a +" (read / write)Open a file and read and write at the end of the file Create a new file
"rb +" (read / write)Open a binary file for reading and writing error
"wb +" (read / write) Create a new binary file for reading and writing Create a new file
"ab +" (read / write)Open a binary file and read and write at the end of the file Create a new file

3, Sequential reading and writing of files

functionFunction nameApply to
Character input functionfgetc All input streams
Character output functionfputcAll output streams
Text line input function fgets All input streams
Text line output functionfputs All output streams
Format input functionfscanf All input streams
Format output function fprintf All output streams
Binary inputfread file
Binary outputfwrite file

As long as the C language program runs, three streams are opened by default:
Standard output stream stdout
Standard input stream stdin
Standard error stream stderr
The types of these three streams are FILE *.

1.fputc and fgetc

fputs is suitable for file stream or standard output stream.

#include <stdio.h>
int main()
{
	FILE* pf = fopen("data.txt", "w");//Open as write
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}
	//Write file
	fputc('n', pf);//Equivalent to the putchar function printf()
	fputc('e', pf);
	fputc('w', pf);
	//Close file
	fclose(pf);
	pf = NULL;
	return 0;
}

fputc can not only write information into files, but also output information to the screen.

#include <stdio.h>
int  main()
{
	fputc('b', stdout);//Standard output stream, which can output information to the screen
	fputc('i', stdout);
	fputc('t', stdout);
	return 0;
}

fgetc reads one character at a time and applies to all input streams.

int main()
{
	FILE* pf = fopen("data.txt", "r");//Open as read
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}
	//read file
	int ch = fgetc(pf);//Read one character at a time
	printf("%c\n", ch);
	ch = fgetc(pf);
	printf("%c\n", ch);
	ch = fgetc(pf);
	printf("%c\n", ch);
	//Close file
	fclose(pf);
	pf = NULL;
	return 0;
}

fgetc can be entered from the file or from the keyboard:

int main()
{
	//read file
	int ch = fgetc(stdin);//Equivalent to getchar() function scanf()
	printf("%c\n", ch);
	ch = fgetc(stdin);
	printf("%c\n", ch);
	ch = fgetc(stdin);
	printf("%c\n", ch);
	
	return 0;
}

2.fgets and fputs

int  main()
{
	FILE* pf = fopen("data.txt", "w");//Write file
	if (pf == NULL)
	{
		perror("fopen");//Failed to open, output error message
		return -1;
	}
	//Write a file, write a line of data
	fputs("hello",pf);
	fputs("world", pf);
	//Close file
	fclose(pf);
	pf = NULL;
	return 0;
}

fgets text input function, applicable to all input streams.

int  main()
{
	FILE* pf = fopen("data.txt", "r");

		if (pf == NULL)
		{
			perror("fopen");
			return -1;
		}
		//read file
		char arr[20] = { 0 };
		fgets(arr, 5, pf);//In fact, there are only four, and another position is' \ 0 '. If int num (the second data) is too long, one line can be read
		printf("%s\n", arr);
		fgets(arr, 5, pf);
		printf("%s\n", arr);
		fgets(arr, 5, pf);
		printf("%s\n", arr);
	//Close file
	fclose(pf);
	pf = NULL;
	return 0;
}

3.fprintf and fscanf

fprintf writes as text

struct S
{
	int n;
	double d;
};
int main() 
{
	struct S s = { 12, 3.14 };
	FILE* pf = fopen("data.txt", "w");
		if (pf == NULL)
		{
			perror("fopen");
			return -1;
		}
		//Write file
		fprintf(pf, "%d %lf", s.n, s.d);
		//Close file
			fclose(pf);
			pf = NULL;
	return 0;
}

fscanf has one more parameter than scanf. fscanf format input.

struct S
{
	int n;
	double d;
};
int main()
{
	struct S s = {0 };
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}
	//read file
	fscanf(pf, "%d %lf", &(s.n),&( s.d));
	printf("%d %lf", s.n, s.d);
	//Close file
	fclose(pf);
	pf = NULL;
	return 0;
}

4.fread and fwrite

Write in binary mode:

struct S
{
	int n;
	double d;
	char name[10];
};
int main()
{
	struct S s = { 100,3.14,"zhang" };
	FILE* pf = fopen("data.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}
	//Write files in binary mode
	fwrite(&s,sizeof(s),1,pf);
	//Close file
	fclose(pf);
	pf = NULL;
	return 0;
}

Binary Reading:

struct S
{
	int n;
	double d;
	char name[10];
};
int main()
{
	struct S s = { 0};
	FILE* pf = fopen("data.txt", "rb");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}
	//Reading files in binary mode
	fread(&s, sizeof(struct S), 1, pf);//The starting position of the file, the size of the data to be read at one time, and the number of elements to be read at one time, are read from the pf stream
	//Print
	printf("%d %lf %s", s.n, s.d, s.name);//100 3.14 zhang
	//Close file
	fclose(pf);
	pf = NULL;
	return 0;
}

5.sprintf and sscanf

struct S
{
	int n;
	double d;
	char name[10];
};
int main()
{
	char arr[100] = { 0 };
	struct S temp = { 0 };
	struct S s = { 100, 3.14, "zhang" };
	//Converts a formatted data into a string
	sprintf(arr, "%d %lf %s", s.n, s.d, s.name);
	//Print as string
	printf("%s\n", arr);
	//Extract a formatted data from the string in the arr
	sscanf(arr, "%d %lf %s", &(temp.n), &(temp.d), temp.name);
	//Print in formatted form
	printf("%d %lf %s\n", temp.n, temp.d, temp.name);
	return 0;
}

scanf: reads formatted data from the standard input stream
fscanf: read formatted data from all input streams
sscanf: read formatted data from string

printf: output the formatted data to the screen (standard output)
fprintf: output formatted data to all output streams (screen / file)
sprintf: convert the formatted data into the corresponding string

4, Random reading and writing of files

1.fseek

Locate the file pointer according to the position and offset of the file pointer.
Function prototype:

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

2.ftell

Returns the offset of the file pointer from the starting position.
Function prototype:

long int ftell ( FILE * stream );

3 rewind

Returns the position of the file pointer to the starting position of the file.
Function prototype:

void rewind ( FILE * stream );

give an example:

int main()
{
	//Open file
	FILE* pf = fopen("data.txt", "r");
	if (NULL == pf)
	{
		perror("fopen");
		return;
	}
	//read file
	//Random reading and writing
	/*int ch = fgetc(pf);
	printf("%c\n", ch);*/

	//Offset back 2 from start position
	fseek(pf,2,SEEK_SET);
	int ch = fgetc(pf);
	printf("%c\n", ch);

	//Offset 2 positions forward from the current position
	fseek(pf, -2, SEEK_CUR);
	 ch = fgetc(pf);
	printf("%c\n", ch);

	//Calculates the offset of the file pointer from the starting position
	int ret = ftell(pf);
	printf("%d\n", ret);

	//Returns the position of the file pointer to the starting position of the file
	rewind(pf);
	ch = fgetc(pf);
	printf("%c\n", ch);

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

5, Text and binary files

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 ASCII code on external memory, it needs to be converted before storage. Files stored in ASCII characters are text files.
All characters are stored in ASCII form, and numerical data can be stored in ASCII form or binary form.
Example:
If the integer 10000 is output to the disk in the form of ASCII code, the disk will occupy 5 bytes (one byte per character), while if it is output in binary form, it will occupy only 4 bytes on the disk.

int main()
{
	//Open file
	FILE* pf = fopen("data.txt", "wb");
	if (NULL == pf)
	{
		perror("fopen");
		return;
	}
	//Write in binary form
	int a = 10000;
	fwrite(&a, 4, 1, pf);
	//Close file
	fclose(pf);
	pf = NULL;
	return 0;
}


The above figure shows the output in binary form (small end storage mode output displayed in hexadecimal form).

6, Determination of end of file reading

In the process of file reading, the return value of 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 reading of the text file ends, and judge whether the return value is EOF (fgetc) or NULL(fgets).
    For example:
  •            fgetc Judge whether the return value is EOF ,To determine whether the file reading is over.
    
  •            fgets Judge whether the return value is NULL ,To determine whether the file reading is over.
    
  • Judge whether the return value is less than the actual number to be read after reading the binary file.
    For example:
  •           fread Judge whether the return value is less than the actual number to be read
    
int main()
{
	//Open file
	FILE* pf = fopen("data.txt", "wb");
	if (NULL == pf)
	{
		perror("fopen");
		return;
	}
	/*int ch = fgetc(pf);
	printf("%c\n", ch);*/
	int ch = 0;
	while (ch = fgetc(pf) != EOF)
	{
		printf("%c\n", ch);
	}

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

feof is the end of file reading. Judge whether it ends at the end of the file.
ferror is the end of file reading. It is judged whether it ends after encountering an error.

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	int c; // Note: int, not char, requires EOF processing
	FILE* fp = fopen("test.txt", "r");
if(!fp) {
	perror("File opening failed");
	return EXIT_FAILURE;
}
//fgetc will return EOF when reading fails or when the file ends
while ((c = fgetc(fp)) != EOF) // Standard C I/O read file cycle
{
	putchar(c);
}
//Judge why it ended
if (ferror(fp))
	puts("I/O error when reading");
else if (feof(fp))
	puts("End of file reached successfully");
fclose(fp);
}

7, File buffer

ANSIC standard uses "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 being used 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 and input it into memory
Flush the 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 by the C compilation system.

#include <stdio.h>
#include <windows.h>
int main()
{
	FILE*pf = fopen("test.txt", "w");
	fputs("abcdef", pf);//Put the code in the output buffer first
	printf("Sleep for 10 seconds-The data has been written. Open it test.txt File, no content found in the file\n");
	Sleep(10000);
	printf("refresh buffer \n");
	fflush(pf);//When the buffer is refreshed, the data of the output buffer is written to the file (disk)
	//Note: fflush cannot be used on higher version VS
	printf("Sleep for another 10 seconds-At this point, open again test.txt File, the file has content\n");
	Sleep(10000);
	//Close file
	fclose(pf);
	//Note: fclose also flushes the buffer when closing the file
	pf = NULL;
	return 0;
}

Because of the existence of buffer, C language needs to refresh the buffer or close the file at the end of file operation. If not, it may cause problems in reading and writing files.

above.

Keywords: C C++ Programming Windows Database

Added by ferhanz on Tue, 28 Sep 2021 10:52:02 +0300