Author's homepage: paper jie's blog_CSDN Blog
Author of this article: Hello everyone, I am paper jie, thank you for reading this article, welcome to build three companies.
This article is included in the "System Analysis of C Language" column, which is carefully crafted for college students and beginners in programming. The author spent a lot of money (time and energy) to build it, and collected all the basic knowledge of algorithms, hoping to help readers.
Other columns: "Detailed Algorithms", "C Language", "C Language - Grammar", etc.
Content sharing: This issue will explain in detail the operation of c language files
Table of contents
Sequential reading and writing of files
fscanf,sscanf 和 fprintf,srpintf
Random reading and writing of files
Judgment of the end of file reading
Why do you need to use files
In the previous structure article, we can use it to write an address book program. After the address book is running, we can add and delete data to the address book. At this time, the data is stored in the memory. When the program ends, the communication The data in the record is returned to the operating system. This involves the issue of our data persistence. We generally have two methods for data persistence: 1. Store the data in the disk; 2. Store the data in the database.
By using files, we can store data on the computer's disk to make the data persistent.
what is a file
A file on disk is a file. In programming, we generally have two kinds of files: program files and data files.
program files
It includes source program file (suffix .c) object file (suffix obj in Windows environment) executable program (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 is running, such as the file that needs to read data from when the program is running, or the file that outputs the content.
file name
A file has a unique file identification name (the file identification name is the file name), so that users can identify and refer to it. The file has three parts: file path + file trunk + file suffix.
Example: D:\practice\test.txt
file opening and closing
file pointer
In the cache file system, the key concept is "file type pointer", referred to as file pointer for short .
Each used file has opened up a corresponding file information area in the memory, which is used to store the relevant information of the file (such as: file name, status, current location, etc.). These information are stored in a structure variable, the structure type is declared by the system, named FILE
In the vs2013 compilation environment, there are the following file type declarations under the header file of stdio.h:
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;
The content contained in the FILEL type of different compilers is not exactly the same, but the same. Whenever a file is opened, the system will automatically create a FILE structure variable according to the file situation, and fill in the information, and the user does not need to care about the details.
Generally, the variables of the FILE structure are maintained through the FILE pointer.
FILE* pf;//文件指针变量
Define pf as a pointer variable pointing to FILE type data. You can point to the file information area of a file through pf. The file can be accessed through the information in the file information area. That is to say: the file related to it can be found through the file pointer variable.
file opening and closing
When the file is read and written, the file is opened first, and the file is closed after use.
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.
//打开文件
FILE * fopen ( const char * filename, const char * mode );
//关闭文件
int fclose ( FILE * stream );
How the file is used: Meaning: If the file does not exist:
"r" (read-only)
|
To enter data, open an existing text file | go wrong |
"w" (write only) |
To output data, open a text file
|
create a new file
|
“a” (append) |
Add data to the end of the text file
|
create a new file |
"rb" (read-only) |
To enter data, open a binary file
|
go wrong
|
wb" (write only)
|
To output data, open a binary file
|
create a new file
|
“ab” (append)
|
append data to the end of a binary file
|
create a new file
|
"r+" (read and write)
|
Open a text file for reading and writing
|
go wrong
|
"w+" (read and write)
|
For reading and writing, suggest a new file
|
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
|
go wrong
|
"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
|
chestnut:
int main()
{
FILE* pf;
pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//写文件
//关闭文件
fclose(pf);
return 0;
}
Because there is no test.txt file under my file, it reports an error
Sequential reading and writing of files
fgetc and fputc
int main()
{
FILE* pf;
pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
int ch = fgetc(pf);
printf("%c ", ch);
ch = fgetc(pf);
printf("%c ", ch);
ch = fgetc(pf);
printf("%c ", ch);
fclose(pf);
pf = NULL;
return 0;
}
int main()
{
FILE* pf;
pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fputc('a', pf);
fputc('b', pf);
fputc('c', pf);
fclose(pf);
pf = NULL;
return 0;
}
fgets and fputs
int main()
{
FILE* pf;
pf = fopen("test.txt", "w");
if (pf == NULL)
{
printf("open");
return 1;
}
fputs("aaaaaa", pf);
fputs("xxxxxxx", pf);
fclose(pf);
pf = NULL;
return 0;
}
Note: The read file ends at num-1 or when a newline is encountered
int main()
{
FILE* pf;
pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
char arr[10] = { 0 };
fgets(arr, 10, pf);
printf("%s", arr);
fclose(pf);
pf = NULL;
return 0;
}
fscanf,sscanf 和 fprintf,srpintf
struct S
{
int a;
double b;
};
int main()
{
FILE* pf;
pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
struct S s = { 1, 3.15 };
fprintf(pf, "%d %f", s.a, s.b);
fclose(pf);
pf = NULL;
return 0;
}
struct S
{
int a;
double b;
};
int main()
{
FILE* pf;
pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
struct S s = { 0 };
fscanf(pf, "%d %lf", &(s.a), &(s.b) );
printf("%d %f", s.a, s.b);
fclose(pf);
pf = NULL;
return 0;
}
struct S
{
int a;
float b;
char ch[10];
};
int main()
{
struct S s = { 10, 19.5, "hello" };
char arr[100] = { 0 };
sprintf(arr, "%d %f %s", s.a, s.b, s.ch);
printf("%s", arr);
}
int main()
{
struct S s = { 10, 19.5, "hello" };
char arr[100] = { 0 };
sprintf(arr, "%d %f %s", s.a, s.b, s.ch);
//printf("%s", arr);
struct S tmp = { 0 };
sscanf(arr,"%d %f %s", &(tmp.a), &(tmp.b), &(tmp.ch));
printf("%d %f %s", tmp.a, tmp.b, tmp.ch);
}
in conclusion:
scanf: reads formatted data from the standard input stream
printf: Write formatted data from the standard output stream
fscanf: read formatted input function for all input streams
fprintf: apply to all output streams write formatted output function
sscanf: read formatted data from a string
sprintf: converts formatted data into strings
fread and fwrite
#include <stdio.h>
struct S
{
int a;
double b;
char arr[10];
};
int main()
{
struct S s = { 1, 3.2, "hello" };
FILE* pf = fopen("test.txt", "wb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fwrite(&s, sizeof(struct S), 1, pf);
return 0;
}
struct S
{
int a;
double b;
char arr[10];
};
int main()
{
struct S tmp = { 0 };
FILE* pf = fopen("test.txt", "rb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fread(&tmp, sizeof(struct S), 1, pf);
printf("%d %f %s\n", tmp.a, tmp.b, tmp.arr);
return 0;
}
Random reading and writing of files
fseek
Position the pointer according to the position and offset of the file pointer
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fseek(pf, 2, SEEK_SET);
int ch = fgetc(pf);
printf("%c\n", ch);
return 0;
}
ftell
Returns the offset of the file pointer relative to the starting position
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fseek(pf, 2, SEEK_SET);
int ch = fgetc(pf);
//printf("%c\n", ch);
int pos = ftell(pf);
printf("%d\n", pos);
return 0;
}
rewind
Return the position of the file pointer to the beginning of the file
text files and binary files
Data files are called text files or binary files, depending on how the data is stored.
Judgment of the end of file reading
misused feof
In the process of reading the file, the return value of the feo function cannot be used to directly determine whether the file is over.
Instead, it acts on the end of the file reading, judging whether the reading fails to end, or the end of the file is encountered. Returning a non-zero value means that the end of the file has been read, otherwise the read fails and ends.
To determine whether the read is complete can be used:
1 Whether the reading of the text file is finished, judge whether the return value is EOF (fgetc) or NULL (fgets)
2. Judging the end of reading the binary text, judging whether the return value is less than the actual number to be read
chestnut:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int c; // 注意:int,非char,要求处理EOF
FILE* fp = fopen("test.txt", "r");
if(!fp) {
perror("File opening failed");
return EXIT_FAILURE;
}
//fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOF
while ((c = fgetc(fp)) != EOF) // 标准C I/O读取文件循环
{
putchar(c);
}
//判断是什么原因结束的
if (ferror(fp))
puts("I/O error when reading");
else if (feof(fp))
puts("End of file reached successfully");
fclose(fp);
}
file buffer