C Advanced: File Operations

C language file operation

what is a file

Data on disk is files.

But in programming, we generally talk about two types of files: program files (such as .c, .h files during compilation and linking), and data files.

program files

Including source program file (suffix .c), object file (suffix .obj for windows environment, suffix .o for linux environment), executable program (suffix .exe for windows environment, no suffix for linux environment) .

data file

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 .

file name

A file must have a file ID for user identification 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 .

file type

Depending on how the data is organized, data files are called text files or binary files .

1. The data is stored in binary form in memory, if it is output to external storage without conversion , it is a binary file.

2. If it is required to store in the form of Ascii code in the external memory , it needs to be converted before storage. The form stored in ASCII characters is the text file.

3. Characters are all stored in ASCII, and numeric values ​​can be stored in either ASCII or binary .

If there is an integer 10000, if it is stored to the disk in the form of ASCII code, it will occupy five bytes on the disk, and if it is stored in binary, it will occupy four bytes on the disk. Let's take a look at why it exists like this.

Let's take a look at the code stored in binary form:

#include<stdio.h>

int main()
{
	int a = 10000;
	//创建一个文件指针,以只写的形式打开或创建test.txt,后面会讲
	FILE* pf = fopen("test.txt", "wb");
	//二进制的形式写入文件中
	fwrite(&a, 4, 1, pf);
	fclose(pf);
	pf = NULL;
}

 The result of opening test.txt with a binary editor in vs is as follows:

 The preceding 00000000 is a meaningless address, while the following data is indeed 10000 in hexadecimal.

file pointer

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 memory.

When planning to read and write a file:

1. Open the file 2. The opened file maintains a file information area

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 in it, and the user does not need to care about the details.

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

Let's create a FILE* pointer variable:

FILE* pf;

Define pf as a pointer variable pointing to FILE type data, which 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. In other words, the file associated with it can be found through the file pointer variable.

for example:

file opening and closing 

The basic steps of file operation: open file -> read and write file -> close file

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 function is used to close the file. (The header file is: stdio.h)

How to use

FILE* fopen(const char* filename,//文件名称
const char* mode//文件的使用方式
)

int fclose(FILE* stream);//文件指针

The following are all ways to open the file (note when the specified file does not exist):

v2-c4773117934a3d2d75abd7b6bbcd1a12_r.jpg (1118×613)

 Take a small chestnut:

#include <stdio.h>

int main()
{
	FILE* pf;
	//test.txt为相对路径,表明这个文件就在程序内。
	pf = fopen("test.txt", "w");
	//如果文件指针pf不为真再进行操作
	if (pf != NULL)
	{
		//文本行输出函数fputs,一会会讲。
		fputs("fopen example", pf);
		//关闭文件
		fclose(pf);
		//将文件指针置为空
		pf = NULL;
	}
	return 0;
}

Sequential reading and writing of files

As long as the C language program is running, three streams are opened by default.

Note: Definition of stream: stream in a file refers to the transmission channel of data between input and output devices (such as hard disks, keyboards, monitors, etc.) and programs. A stream can be seen as an abstraction of a sequence of bytes, which abstracts input and output into a continuous data stream, allowing programs to access and process the contents of a file through the stream.

1. Standard input stream stdin FILE*: used for keyboard to receive input data.

2. Standard output stream stdout FILE*: used to output data to the screen.

3. Standard error stream stderr FILE*: used to output error information to the screen.

 

 

Comparison and use of important functions

fgetc and fputc

1. Function prototype:int fgetc(FILE* stream);

Function: used to read a file , fgetcused to read a character from the specified file stream ( stream), and return the integer representation (ASCII code value) of the character read. It returns EOF(End of File) if the end of the file is reached or a read error occurs.

2. Function prototype:int fputc(int ch, FILE* stream);

Function: used to write to a file , fputcthe function writes the specified character chto the specified file stream stream. Returns the character written if the write was successful, or EOF(usually -1) if an error occurred.

fscanf and fprintf

fscanffunction:

  • Function prototype:int fscanf(FILE *stream, const char *format, ...);

  • Function: fscanfRead data from the specified file stream and parse it according to the specified format string. It's similar scanf, but it reads data from a file instead of standard input . fscanfReturns the number of items successfully read and parsed, or if a read error occurs or the end of the file is reached EOF.

2.fprintffunction:

  • Function prototype:int fprintf(FILE *stream, const char *format, ...);

  • Function: fprintfWrite data to the specified file stream, format the data according to the specified format string and write to the file. It is similar printf, but writes the output data to a file instead of standard output . fprintfReturns the number of characters successfully written, or a negative value if a write error occurred.

sscanf and sprintf

1.sscanffunction:

  • Function prototype:int sscanf(const char *str, const char *format, ...);

  • Function: Read data sscanffrom the specified string strand parse it according to the specified format string. It's similar scanf, but reads data from a string instead of standard input. sscanfReturns the number of items successfully read and parsed.

2.sprintffunction:

  • Function prototype:int sprintf(char *str, const char *format, ...);

  • Function: Format and output the data into a string sprintfaccording to the specified format string . It is similar , but writes the output data to a string instead of standard output. Returns the number of characters successfully written.formatstrprintfsprintf

Take a chestnut:

#include <stdio.h>

int main()
{
	char str[] = "20 20";
	int num1, num2;
	sscanf(str, "%d %d", &num1, &num2);
	printf("the two numbers are %d and %d", num1, num2);
	return 0;
}

result:

 Random reading and writing of files

fseek function: Define the file pointer according to the starting position and offset of the file.

int fseek(FILE* stream,//文件指针
          long int offset,//偏移量,是整数就正向偏移,是负数就负向偏移
          int origin//起始位置
//包括:SEEK_SET(文件起始位置),SEEK_CUR(文件指针当前位置),SEEK_END(文件结束位置)
)

for example:

#include <stdio.h>

int main()
{
	FILE* pf;
	pf = fopen("test.txt", "wb");
	fputs("this is an apple", pf);
	fseek(pf, 9, SEEK_SET);
	fputs("sam", pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

It can be seen that the string "sam" is inserted after the string offset 9.

pftell function: Calculate the offset of the file pointer equivalent to the starting position.

long int ftell(FILE* stream) 

for example:

#include <stdio.h>

int main()
{
	FILE* pf;
	long size;

	pf = fopen("test.txt", "rb");
	if (pf == NULL)
	{
		perror("Error opening file");
	}
	else
	{
		fseek(pf, 0, SEEK_END);
		size = ftell(pf);
		fclose(pf);
		pf = NULL;
		printf("size of myfile.txt:%ld bytes.\n", size);
	}
	return 0;
}

The original string this is asample is still read here, so the calculated result is 16.

rewind function: let the file pointer return to the beginning of the file

void* rewind(FILE* stream).

#include <stdio.h>

int main()
{
	int n;
	FILE* pf;
	//创建一个字符串
	char buffer[27];

	//为了读和写建立了一个新的文件myfile.txt
	pf = fopen("myfile.txt", "w+");
	//利用文件指针向文件依次写入A到Z26个字符
	for (n = 'A'; n <= 'Z'; n++)
	{
		fputc(n, pf);
	}
	//让文件返回到起始位置
	rewind(pf);
	//又再次在文件开始位置读取26个字符并放入buffer中
	fread(buffer, 1, 26, pf);
	fclose(pf);
	pf = NULL;
	//第27个元素设为'\0',以便截断字符串
	buffer[26] = '\0';
	puts(buffer);
	return 0;
}

Judgment of end of file

misused feof

Keep in mind: in the process of reading the file, the return value of the feof function cannot be used to directly determine whether the file is over.

Instead, it is applied when the file reading ends, judging whether the reading fails to end, or the end of the file is met .

So how should we judge whether the file is over?

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

For example: fgetc judges whether it is EOF.

          fgets judges whether the return value is NULL.

2. Judging the end of reading the binary file, and judging whether the return value is less than the actual number to be read .

For example: fread judges whether the return value is less than the number to be read.

The correct way to use it is as follows:

text file

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int c;//注意int ,不是char,要求处理EOF。
	FILE* fp = fopen("test.txt", "r");
	if (fp == NULL)
	{
		perror("File opening filed!");
		return;
	}
	//fgetc当读取失败的时候或者遇见文件尾的时候,都会返回EOF
	while ((c = fgetc(fp)) != EOF)
	{
		putchar(c);
	}
	//判断是什么原因结束的
	if (ferror(fp))
	{
		puts("\nI\O error when reading");
	}
	else if (feof(fp))
	{
		puts("\nEnd of file reached successfully");
	}
	fclose(fp);
	fp = NULL;
	return 0;
}

Well, that’s all for the file pointers, welcome everyone to point out!

Guess you like

Origin blog.csdn.net/asdssadddd/article/details/131859043