[C Advanced] File Operation (1)

content

 

1. Why use files

2. What is a file

    (1) Program files

    (2) Data file

    (3) File name

3. File opening and closing

    (1) File pointer

    (2) Opening and closing of files

4. Sequential reading and writing of files

   (1) fgetc and fputc

              fgets和fputs

              fscanf和fprintf

              fread和fwrite

   (2) Compare a set of functions


1. Why use files

  • Using files, we can store data directly on the hard disk of the computer, which makes the data persistent. Prevent data loss.

2. What is a file

  • 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 functions).

(1) Program files

Including source program files ( suffixed with .c ), target files ( suffixed with .obj in windows environment ), executable programs ( suffixed with .exe in windows environment ).

  • As shown in the figure:

In the above figure, the test.c file is the program file

  • Interpret the executable program:

Let's just write a bunch of code:

#include<stdio.h>
int main()
{
	printf("hehe\n");
	return 0;
}

After running, a Debug folder will appear

 The suffix of .exe is the executable program, that is, the program file

  •  Interpret the object file:

   The file named with the suffix .obj in the above figure is the object file, which is a temporary file generated by the program during compilation

(2) 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 from which the content is output.

  • As shown in the figure:

 In the above picture, the test.txt file was created by myself, it is the data file 

  • The input and output of the data processed in the previous chapters are all based on the terminal, that is, the data is input from the keyboard of the terminal, and the operation result is displayed on the display.
  • In fact, sometimes we will output the information to the disk, and then read the data from the disk into the memory for use when needed, and the file on the disk is processed here.

(3) File name

A file must have a unique file identifier for user identification and reference.

The file name contains 3 parts: file path + file name trunk + file suffix

  • For example: c:\code\test.txt
  1. c:\code\  ---> file path
  2. test         ---> filename trunk
  3. .txt          ---> file suffix

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

3. File opening and closing

(1) File pointer

 In the buffered file system, the key concept is "file type pointer", or "file pointer" for short.

Each used file opens 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 state 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.

  • for example:

  •  Example: The stdio.h header file provided by the VS2013 compilation environment has the following file type declarations:
struct _iobuf {
	char* _ptr;
	int _cnt;
	char* _base;
	int _flag;
	int _file;
	int _charbuf;
	int _bufsiz;
	char* _tmpfname;
};
typedef struct _iobuf FILE;

The contents of the FILE types of different C compilers are not exactly the same, 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, 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.

  • Next we can create a pointer variable of FILE*:
FILE* pf;//文件指针变量

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

  • for example:

  • Another example:

(2) Opening and closing of files

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

When writing a program, when opening a file, it will return a FILE* pointer variable to point to the file, which is also equivalent to establishing the relationship between the pointer and the file.

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

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

fopen parameter meaning:

  • Parameter 1: file name
  • Parameter 2: File opening method

Open as follows:

How the file is used meaning If 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"(追加) Append 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"(追加) Append data to the end of a binary file error
"r+" (read and write) Open a text file for reading and writing error
"w+" (read and write) Create a new file for reading and writing create a new file
"a+" (read and write) Open a file for reading and writing at the end of the file create a new file
"rb+" (read and write) Open a binary file for reading and writing error
"wb+" (read and write) Create a new binary file for reading and writing create a new file
"ab+" (read and write) Open a binary file for reading and writing at the end of the file create a new file
  • E.g:

Before giving an example, delete the original test.txt file to verify the specific meaning of the file usage.

  •  Take " w " as an example:
#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	//……
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

After the program runs, we will see that a file called test.txt is indeed created:

  • But if " r " is used as an example: if test.txt itself does not exist, the program will report an error

4. Sequential reading and writing of files

Before the specific explanation, we need to talk about the concept of flow:

  • A C language program, as long as it runs, opens 3 streams by default:
  1. stdin - standard input stream - keyboard
  2. stdout - standard output stream - screen
  3. stderr - standard error stream - screen

The above three are all FILE*

Function Function name apply to
character input function fgetc all input streams
character output function fputc all output streams
Text line input function fgets all input streams
Text line output function fputs all output streams
format input function fscanf all input streams
formatted output function fprintf all output streams
binary input fread document
binary output fwrite document

(1) fgetc and fputc

  •  fputc:

  •  Example:
#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	fputc('b', pf);
	fputc('i', pf);
	fputc('t', pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

When we punched the test.txt file with Notepad, we found that the bit has indeed been written

  •  fputs can also output to the screen:
#include<stdio.h>
int main()
{
	fputc('b', stdout);
	fputc('i', stdout);
	fputc('t', stdout);
	return 0;
}

  • fgetc:

First, we put the string of abcdef back into the test.txt file

  • Reading data from a file stream using fgetc

#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	int ret = fgetc(pf);
	printf("%c\n", ret);
	ret = fgetc(pf);
	printf("%c\n", ret); 
	ret = fgetc(pf);
	printf("%c\n", ret);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

  •  fgetc can also read from the standard input stream on the keyboard:
#include<stdio.h>
int main()
{
	int ret = fgetc(stdin);
	printf("%c\n", ret);
	ret = fgetc(stdin);
	printf("%c\n", ret);
	ret = fgetc(stdin);
	printf("%c\n", ret);
	return 0;
}

 The above is to read or write one character by one, and it can also be read or written line by line

fgets和fputs

  • fputs:

#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件 - 按照行来写
	fputs("abcdef\n", pf);
	fputs("qwertyuiop\n", pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

When we open the test.txt file, those two lines of strings have already been entered:

  •  fgets:

 n represents the maximum number of reads

#include<stdio.h>
int main()
{
	char arr[10] = { 0 };
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件 - 按照行来写
	fgets(arr, 4, pf);
	printf("%s\n", arr);
	fgets(arr, 4, pf);
	printf("%s\n", arr);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

 Although n represents the maximum number of readings, the last one needs to put \0, so even if n=4 here, there are only 3 characters in each output, and the last one is \0, and it can only be read after one line. to the next line.

fscanf和fprintf

  • fprintf:

#include<stdio.h>
struct S
{
	char arr[10];
	int num;
	float sc;
};
int main()
{
	struct S s = { "abcdef",10,5.5f };
	//对格式化数据进行写文件
	FILE* pf = fopen("test.txt", "w");
	if (NULL == pf)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	fprintf(pf, "%s %d %f", s.arr, s.num, s.sc);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}
  • When we run the program, open the test.txt file:

At this point, a formatted data has been written into the file.

Can the information in the file be read out? Read it out and restore it to that structure, then use fscanf:

  • fscanf:

#include<stdio.h>
struct S
{
	char arr[10];
	int num;
	float sc;
};
int main()
{
	struct S s = { "abcdef",10,5.5f };
	//对格式化数据进行写文件
	FILE* pf = fopen("test.txt", "r");
	if (NULL == pf)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	fscanf(pf, "%s %d %f", s.arr, &(s.num), &(s.sc));
	//打印
	printf("%s %d %f", s.arr, s.num, s.sc);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}
  •  Run as follows:

fread和fwrite

Next is the binary read and write

  • fwirte :

 

#include<stdio.h>
struct S
{
	char arr[10];
	int num;
	float sc;
};
int main()
{
	struct S s = { "abcdef",10,5.5f };
	//以二进制的形式写文件
	FILE* pf = fopen("test.txt", "w");
	if (NULL == pf)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	fwrite(&s, sizeof(struct S), 1, pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}
  •  When we open the test.txt file, we see:

Since we can't see what fwrite wrote with the naked eye, there must be something that we can understand. At this time, we use fread:

  • fread: 

#include<stdio.h>
struct S
{
	char arr[10];
	int num;
	float sc;
};
int main()
{
	struct S s = { 0 };
	//以二进制的形式读文件
	FILE* pf = fopen("test.txt", "r");
	if (NULL == pf)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	fread(&s, sizeof(struct S), 1, pf);
	printf("%s %d %f\n", s.arr, s.num, s.sc);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}
  • After running:

 It can be seen that fread and fwrite are a pair, fwrite writes, and fread reads.

(2) Compare a set of functions

sscanf and sprintf are special:

  •  sprintf: take a formatted data and convert it to a string

  •  Example:
#include<stdio.h>
struct S
{
	char arr[10];
	int num;
	float f;
};
int main()
{
	struct S s = { "hello",20,5.5f };
	char buf[100] = { 0 };
	//sprintf 把一个格式化数据转换成字符串
	sprintf(buf, "%s %d %f", s.arr, s.num, s.f);
	printf("%s\n", buf);
	return 0;
}

  •  sscanf: read a formatted data from a string

#include<stdio.h>
struct S
{
	char arr[10];
	int num;
	float f;
};
int main()
{
	struct S s = { "hello",20,5.5f };
	struct S tmp = { 0 };
	char buf[100] = { 0 };
	//sprintf 把一个格式化数据转换成字符串
	sprintf(buf, "%s %d %f", s.arr, s.num, s.f);
	printf("%s\n", buf);
	//从buf字符串中还原出一个结构体数据
	sscanf(buf, "%s %d %f", tmp.arr, &(tmp.num), &(tmp.f));
	printf("%s %d %f", tmp.arr, tmp.num, tmp.f);
	return 0;
}

Guess you like

Origin blog.csdn.net/bit_zyx/article/details/122848956