Note: This blog is written word by word by the blogger, which is not easy. Please respect the originality, thank you all!
Overview
1) Disk files and device files
-
Disk file
refers to a set of ordered collections of related data, usually stored on external media (such as disks) and loaded into memory only when used. -
Device file
In the operating system, each input and output device connected to the host is regarded as a file, and their input and output are equivalent to reading the disk file. and write.
2) Classification of disk files
Computer storage is physically binary, so physically all disk files are essentially the same: sequential storage in bytes.
From the perspective of user or operating system usage (logically), files are divided into:
- Text file: Character encoding based file
- Binary file: Value-based encoding
3) Text files and binary files
3.1 Text files
- is based on character encoding. Common encodings include
ASCII
,UNICODE
, etc. - Generally, you can use a text editor to open it directly.
- The storage form (ASCII code) of number
5678
inASCII
is: (first convert5678
to a> 00110101 00110110 00110111 00111000, and then converted to binary)ASCII
code value53、54、55、56
3.2 Binary files
- Based on value coding, you can specify what a certain value means based on the specific application.
- Output the data in the memory to the disk as it is stored in the memory
- The storage form (binary code) of number
5678
is: - 00010110 00101110
Opening and closing files
1) File pointer
InC
language, a pointer variable is used to point to a file. This pointer is called a file pointer.
typedef struct
{
short level; //缓冲区"满"或者"空"的程度
unsigned flags; //文件状态标志
char fd; //文件描述符
unsigned char hold; //如无缓冲区不读取字符
short bsize; //缓冲区的大小
unsigned char *buffer;//数据缓冲区的位置
unsigned ar; //指针,当前的指向
unsigned istemp; //临时文件,指示器
short token; //用于有效性的检查
}FILE;
FILE
is a structure type of file information defined by the system using typedef
. The structure contains information such as file name, file status and current location of the file.
DeclarationFILE
The information of the structure type is included in the header file"stdio.h"
, generally setting a pointer to the FILE
type variable pointer variables, and then reference theseFILE
type variables through it. Through the file pointer, various operations can be performed on the file it points to.
C
There are three special file pointers in the language that are opened by the system by default and can be used directly by users without defining them:
- stdin: standard input, defaults to the current terminal (keyboard), we use the
scanf
,getchar
functions Data is obtained from this terminal by default. - stdout: standard output, defaults to the current terminal (screen), we use the
printf
,puts
functions Information is output to this terminal by default. - stderr: Standard error, defaults to the current terminal (screen), and the
perror
function we use defaults to output information to this terminal.
2) Opening the file
Any file must be opened before use:
- Header file:
#include <stdio.h>
- Define function:
FILE * fopen(const char * filename, const char * mode);
- Function: open file
- Parameters:
filename:
The name of the file to be opened, plus the path as needed
mode:
The mode setting for opening the file - Return value:
Success: file pointer
Failure:NULL
Several forms of the first parameter:
FILE *fp_passwd = NULL;
//相对路径:
//打开当前目录passdw文件:源文件(源程序)所在目录
FILE *fp_passwd = fopen("passwd.txt", "r");
//打开当前目录(test)下passwd.txt文件
fp_passwd = fopen("./test/passwd.txt", "r");
//打开当前目录上一级目录(相对当前目录)passwd.txt文件
fp_passwd = fopen("../passwd.txt", "r");
//绝对路径:
//打开C盘test目录下一个叫passwd.txt文件
fp_passwd = fopen("c:/test/passwd.txt","r");
Several forms of the second parameter (how to open the file):
open mode | meaning |
---|---|
r orrb |
Open a text file in read-only mode (does not create the file, and reports an error if the file does not exist) |
w orwb |
Open the file for writing (clear the file if it exists, create a file if it does not exist) |
a orab |
Open the file in append mode, add content at the end, or create the file if it does not exist |
r+ orrb+ |
Open the file for reading and writing (does not create a new file) |
w+ orwb+ |
Open the file in a readable and writable manner (clear the file if it exists, create a file if it does not exist) |
a+ orab+ |
Open the file in add mode, open the file and change the file at the end, create the file if it does not exist |
Notice:
b
means binary mode.b
is only valid inWindows
and used inLinux
.r
The result is the same asrb
Unix
All text file lines under andLinux
end with\n
, and all text file lines underWindows
is\r\n
end- present
Windows
under the flat table, hereafter “ text ”< /span>b
: Method opening statement, no addition - When reading the file, the system will convert all "
\r\n
" into "\n
" - When writing to a file, the system will convert "
\n
" into "\r\n
" for writing - Open the file in “ binary” mode, then Neither reading nor writing will perform such conversion
- in
Unix/Linux
under the flat table, “ text ”” Production and character code original code input and output model free zone separation ,“” two-way system “ give\r\n
Example 1: Open a text file in read-only mode (do not create the file, and report an error if the file does not exist)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
//打开一个文件,成功返回FILE结构体地址,失败返回NULL
// 返回的文件流指针标识了打开的那个文件
FILE* fp = fopen("hello.txt", "r"); // 只读,不创建文件,若文件不存在则报错
if (NULL == fp)
{
perror("open error");
return;
}
return 0;
}
输出结果
open error: No such file or directory
Example 2: Open the file for writing (clear the file if it exists, create a file if it does not exist)
FILE* fp = fopen("hello.txt", "w"); // 以写方式打开文件(如果文件存在则清空文件,文件不存在则创建一个文件)
if (NULL == fp)
{
perror("open error");
return;
}
Edit the"hello.txt
" file, fill in the data and save it. If the code is executed again, the file content will be cleared
3) Closing of files
Any file should be closed after use:
-
Open files will occupy memory resources. If they are always opened and not closed, a lot of memory will be consumed.
-
The number of files a process can open at the same time is limited. If the maximum number of files opened at the same time is exceeded, calling again
fopen
to open the file will fail -
If there is no explicit call
fclose
to close the open file, the operating system will be shut down when the program exits. -
Header file:
#include <stdio.h>
-
Define function:
int fclose(FILE * stream);
-
Function: Close the file previously opened by fopen(). This action writes the buffer data to the file and releases the file resources provided by the system.
-
Parameter:
stream:
File pointer -
Reply:
Success:0
Failure:-1
FILE* fp = fopen("hello.txt", "w"); // 以写方式打开文件(如果文件存在则清空文件,文件不存在则创建一个文件)
if (NULL == fp)
{
perror("open error");
return -1;
}
fclose(fp);
Sequential reading and writing of files
1) Read and write files fgetc and fputc according to characters
1.1 Write files
- Header file:
#include <stdio.h>
- Define function:
int fputc(int ch, FILE * stream);
- Function: Convert
ch
tounsigned char
and then write it to the file specified bystream
- Parameters:
ch:
Characters to be written to the file
stream:
File pointer - Return value:
Success: Characters successfully written to the file
Failure: Return-1
Example 1:Clear write
FILE* fp = fopen("hello.txt", "w");
fputc('a', fp);
fclose(fp);
Example 2:Additional transcription
FILE* fp = fopen("hello.txt", "a");
fputc('b', fp);
fclose(fp);
Example 3:Clear loop writing
FILE* fp = fopen("hello.txt", "w");
char buf[] = "this is a test for fputc";
int i = 0;
int n = strlen(buf);
for (i = 0; i < n; i++)
{
//往文件fp写入字符buf[i]
int ch = fputc(buf[i], fp);
printf("ch = %c\n", ch);
}
fclose(fp);
1.2 Reading files
- Header file:
#include <stdio.h>
- Define function:
int fgetc(FILE * stream);
Function: Read a character from the file specified by Parameters:stream
a> Failure: < /span> Success: Return the character read Return value: File pointer
stream:
-1
Example:Read the contents of the file
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
FILE* fp = fopen("hello.txt", "r");
char buf[128] = "";
int i = 0;
while ((buf[i++] = fgetc(fp)) != -1);
printf("%s\n", buf);
return 0;
}
1.3 End of file
In C
languages, EOF
represents the end-of-file character (end of file
). In the while
loop, EOF
is used as the end of file mark, and in , EOF
is used as the file The file with the end mark must be a text file. In text files, data are stored in the form of character ASCII
code values. We know that the range of ASCII
code value is 0~127
, and -1
is impossible, so we can use EOF
As the end of file mark.
#define EOF (-1)
Example:UseEOF
as the terminator, problems
// 写入-1
FILE* fp = fopen("hello.txt", "w");
if (NULL == fp)
{
perror("open error");
return -1;
}
char buf[10] = {
97,-1,-2,98,99};
int i = 0;
while (buf[i] != 0)
{
fputc(buf[i], fp);
i++;
}
fclose(fp);
int main()
{
FILE* fp = fopen("hello.txt", "r");
char buf[128] = "";
int i = 0;
while ((buf[i++] = fgetc(fp)) != EOF);
printf("%s\n", buf);
return 0;
}
When storing data in binary form into a file, the value -1
will appear, so EOF
cannot be used as the end of the binary file. logo. To solve this problem, ANSI C
provides a feof
function to determine whether the file ends. The feof function can be used to judge both binary files and text files.
- Header file:
#include <stdio.h>
- Define function:
int feof(FILE * stream);
- Function: Detect whether the end of the file has been read. What is judged is the content of the last " read operation " , not the current Location content (previous content).
- Parameter:
stream:
File pointer - Return value:
Not0
Value: The end of the file has been reached
0:
The end of the file has not been reached
Example:Usefeof
function to determine whether the file ends
int main()
{
FILE* fp = fopen("hello.txt", "r");
char buf[128] = "";
int i = 0;
do
{
buf[i++] = fgetc(fp);
} while (!feof(fp));
printf("%s\n", buf);
return 0;
}
1.4 Intensive training: implement cp and cat commands
Case 1:Copy text file
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void copyFile(char srcFileName[128], char dstFileName[128])
{
// 打开src文件 创建dst文件
FILE* fpread = fopen(srcFileName, "r");
FILE* fpwrite = fopen(dstFileName, "w");
if (NULL == fpread || NULL == fpwrite)
{
perror("open error");
return -1;
}
while (1)
{
int ch;
// 读取src一个字符
ch = fgetc(fpread);
if (feof(fpread))
break;
// 写入到dst文件
fputc(ch, fpwrite);
}
//关闭
fclose(fpread);
fclose(fpwrite);
}
int main()
{
char srcFileName[128] = "hello.txt";
char dstFileName[128] = "hello2.txt";
copyFile(srcFileName, dstFileName);
return 0;
}
Case 2:Copy image files
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void copyFile(char srcFileName[128], char dstFileName[128])
{
// 打开src文件 创建dst文件
FILE* fpread = fopen(srcFileName, "rb");
FILE* fpwrite = fopen(dstFileName, "wb");
if (NULL == fpread || NULL == fpwrite)
{
perror("open error");
return -1;
}
while (1)
{
int ch;
// 读取src文件
ch = fgetc(fpread);
if (feof(fpread))
break;
// 写入到dst文件
fputc(ch, fpwrite);
}
//关闭
fclose(fpread);
fclose(fpwrite);
}
int main()
{
char srcFileName[128] = "csdn_cdtaogang_blog.png";
char dstFileName[128] = "my_csdn_blog.png";
copyFile(srcFileName, dstFileName);
return 0;
}
Case 3:Implement thecat
command and output the file content to the terminal
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
// 打开文件
FILE *fpread = fopen("04拷贝案例.c", "r");
if (NULL == fpread)
{
perror("open error");
return -1;
}
// 读取文件
int ch;
while (1)
{
ch = fgetc(fpread);
if (feof(fpread))
break;
fputc(ch, stdout); //输出到终端
}
fclose(fpread);
return 0;
}
2) Read and write files fgets and fputs according to the line
2.1 Write files
- Header file:
#include <stdio.h>
- Define function:
int fputs(const char * str, FILE * stream);
Function: Write the string specified bystr
into the file specified bystream
, the string terminator'\0'
is not written to the file. - Parameters:
str:
String
stream:
File pointer - Reply:
Success:0
Failure:-1
Example 1:Write a string to a file
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
// 打开文件
FILE *fpread = fopen("a.txt", "w");
if (NULL == fpread)
{
perror("open error");
return -1;
}
// 写入字符串
char buf[] = "hellocdtaogang";
fputs(buf, fpread);
return 0;
}
Example 2:Write data to the file line by line, end writing when encountering\0
, encounter\n
Just wrap
int main()
{
// 打开文件
FILE *fpread = fopen("a.txt", "w");
if (NULL == fpread)
{
perror("open error");
return -1;
}
// 写入字符串,遇到\0就结束
char buf[] = "hello\0cdtaogang";
fputs(buf, fpread);
return 0;
}
int main()
{
// 打开文件
FILE *fpread = fopen("a.txt", "w");
if (NULL == fpread)
{
perror("open error");
return -1;
}
// 写入字符串,遇到\0就结束,遇到\n就换行
//char buf[] = "hello\0cdtaogang";
char buf[] = "hello\ncdtaogang";
fputs(buf, fpread);
return 0;
}
2.2 Reading files
- Header file:
#include <stdio.h>
- Define function:
char * fgets(char * str, int size, FILE * stream);
- Function: Read characters from the file specified by
stream
and save them to the memory space specified bystr
until a newline character appears and the file is read. At the end or untilsize - 1
characters have been read, characters'\0'
will be automatically added at the end to end the string. - Parameter:
str:
String
size:
Specifies the maximum length of the read string (size - 1
)
stream:
File pointer - Return value:
Success: successfully read string
End of file read or error:NULL
Example 1:Read a string from a file
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
// 打开文件
FILE* fpread = fopen("a.txt", "r");
if (NULL == fpread)
{
perror("open error");
return -1;
}
char buf[1024] = "";
// 读取文件
fgets(buf, sizeof(buf), fpread);
printf("%s", buf);
fclose(fpread);
return 0;
}
Example 2:Read a string from the file and end when it encounters\n
Example 3:Use fgets
and fputs
to complete the copy of the text file (Binary file image reading cannot be used because string binary files have many 0s. fgets stops reading when it encounters 0. The same goes for fputs when writing files, so they can only operate text files< a i=5>)
int main()
{
// 打开a文件 创建b文件
FILE* fpread = fopen("a.txt", "r");
FILE* fpwrite = fopen("b.txt", "w");
if (NULL == fpread || NULL == fpwrite)
{
perror("open error");
return -1;
}
char buf[128] = "";
char* p = NULL;
while (1)
{
// 读取a文件
p = fgets(buf, sizeof(buf), fpread);
if (NULL == p)
break;
// 写入到b文件
fputs(buf, fpwrite);
}
//关闭
fclose(fpread);
fclose(fpwrite);
return 0;
}
2.3 Intensive training: file version of four arithmetic operations
There is a file of uncertain size. Each line contains a four-arithmetic expression. The result has not yet been calculated. Write a program to automatically calculate the result and then modify the file.
Step one: Randomly generate10个
four arithmetic expressions and write them to the file.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define CALC_NUM 10 // 要生成四则运算表达式的个数
// 获取10个四则运算表达式并写入到文件中
void write_data()
{
// 生成并打开calc.txt文件
FILE* fp = fopen("calc.txt", "w");
if (NULL == fp)
{
perror("open error");
return -1;
}
// 设置随机种子
srand(time(NULL));
// 定义基本运算符数组
char ysf[] = {
'+', '-', '*', '/' };
int a, b = 0;
char c = 0;
// 定义一个buf数组来保存四则运算表达式
char buf[128] = "";
for (int i = 0; i < CALC_NUM; i++)
{
// 产生随机数1~100
int a = rand() % 100 + 1;
int b = rand() % 100 + 1;
// 随机产生0~3的数
int c = rand() % 4; // 0,1,2,3 对应运算符数组下标
// 组包
sprintf(buf, "%d%c%d=\n", a, ysf[c], b);
printf(buf);
// 写入到calc.txt文件中
fputs(buf, fp);
}
// 关闭文件
fclose(fp);
}
int main()
{
// 调用
write_data();
return 0;
}
Step 2: Readcalc.txt
Read the contents of the file line by line, unpack the calculation results after reading them once, and then package the results into expressions< /span>
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define CALC_NUM 10 // 要生成四则运算表达式的个数
#define FILE_PATH "calc.txt" // 文件路径
// 封装打开文件方法
FILE* open_file(char* str)
{
FILE* fp = fopen(FILE_PATH, str);
if (NULL == fp)
{
perror("open error");
return -1;
}
return fp;
}
// 封装关闭文件方法
void close_file(FILE* fp)
{
fclose(fp);
return;
}
// 获取10个四则运算表达式并写入到文件中
void write_data()
{
// 生成并打开calc.txt文件
FILE* fp = open_file("w");
// 设置随机种子
srand(time(NULL));
// 定义基本运算符数组
char ysf[] = {
'+', '-', '*', '/' };
int a, b = 0;
char c = 0;
// 定义一个buf数组来保存四则运算表达式
char buf[128] = "";
for (int i = 0; i < CALC_NUM; i++)
{
// 产生随机数1~100
int a = rand() % 100 + 1;
int b = rand() % 100 + 1;
// 随机产生0~3的数
int c = rand() % 4; // 0,1,2,3 对应运算符数组下标
// 组包
sprintf(buf, "%d%c%d=\n", a, ysf[c], b);
printf(buf);
// 写入到calc.txt文件中
fputs(buf, fp);
}
// 关闭文件
close_file(fp);
}
void read_data()
{
// 读取文件
FILE* fp = open_file("r");
int a, b = 0;
char c = 0;
char* p = NULL;
char buf[128] = "";
char new_buf[128] = "";
int res = 0;
while (1)
{
p = fgets(buf, sizeof(buf), fp); //读一行的数据72*65=\n
if (NULL == p)
{
break;
}
// 拆包
sscanf(buf, "%d%c%d", &a, &c, &b); // 72*65
// switch判断运算符
switch (c)
{
case '+':
res = a + b;
break;
case '-':
res = a - b;
break;
case '*':
res = a * b;
break;
case '/':
res = a / b;
break;
}
// 再组包,将计算结果组进去
sprintf(new_buf, "%d%c%d=%d\n", a, c, b, res); // 72*65=4680\n
printf("%s", new_buf);
}
}
int main()
{
// 写入
write_data();
printf("\n");
// 读取
read_data();
return 0;
}
Step 3: If you write the result data directly from the second step, the original expression data will be overwritten, such ascalc.txt
file13+15=28\n34-21=13\n...
Writing after reading the first \n
will directly overwrite the data after \n
, so the subsequent data cannot be read. The solution is Just save each row of packed data into a two-dimensional array
void read_data()
{
// 读取文件
FILE* fp = open_file("r");
int a, b = 0;
char c = 0;
char* p = NULL;
char buf[128] = "";
char new_buf[128] = "";
int res = 0;
// 定义二维数组保存每行组包结果数据
char new_buff[10][128] = {
0 };
int i= 0;
while (1)
{
p = fgets(buf, sizeof(buf), fp); //读一行的数据72*65=\n
if (NULL == p)
{
break;
}
// 拆包
sscanf(buf, "%d%c%d", &a, &c, &b); // 72*65
// switch判断运算符
switch (c)
{
case '+':
res = a + b;
break;
case '-':
res = a - b;
break;
case '*':
res = a * b;
break;
case '/':
res = a / b;
break;
}
// 再组包,将计算结果组进去,
//sprintf(new_buf[i], "%d%c%d=%d\n", a, c, b, res); // 72*65=4680\n
//printf("%s", new_buf);
sprintf(new_buff[i], "%d%c%d=%d\n", a, c, b, res); // 72*65=4680\n
i++;
}
// 关闭文件
close_file(fp);
// 再次打开calc.txt文件,写入含结果的四则运算表达式
fp = open_file("w");
for (int j = 0; j < i; j++)
{
fputs(new_buff[j], fp);
}
// 关闭文件
close_file(fp);
}
You can also write the newly packaged result data into a pointer array. You only need to apply for space with malloc to save the packaged data.
char* new_buff[10] = {
NULL };
int i= 0;
while (1)
{
p = fgets(buf, sizeof(buf), fp); //读一行的数据72*65=\n
if (NULL == p)
{
break;
}
// 拆包
sscanf(buf, "%d%c%d", &a, &c, &b); // 72*65
// switch判断运算符
switch (c)
{
case '+':
res = a + b;
break;
case '-':
res = a - b;
break;
case '*':
res = a * b;
break;
case '/':
res = a / b;
break;
}
// 再组包,将计算结果组进去,
//sprintf(new_buf[i], "%d%c%d=%d\n", a, c, b, res); // 72*65=4680\n
//printf("%s", new_buf);
new_buff[i] = (char*)malloc(128);
sprintf(new_buff[i], "%d%c%d=%d\n", a, c, b, res); // 72*65=4680\n
i++;
}
3) Follow the format files fprintf and fscanf
3.1 Write files
- Header file:
#include <stdio.h>
- Define function:
int fprintf(FILE * stream, const char * format, ...);
- Function: Convert and format data according to parameter
format
string, and then output the result to the file specified bystream
, specify the occurrence string end character'\0'
. - Parameter:
stream:
Opened file
format:
String format, usage is the same asprintf()
- Return value:
Success: The number of characters actually written to the file
Failure:-1
Example:Usefprintf
Proportionsprint
Organizationfputs
Copying
printf("%04d:%02d:%02d", year, month, day);
sprintf(buf, "%04d:%02d:%02d", year, month, day)
fprintf(fp, "%04d:%02d:%02d", year, month, day)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main()
{
int year = 2022;
int month = 12;
int day = 2;
char buf[128] = "";
FILE* fp = NULL;
fp = fopen("fprintf.txt", "w");
if (!fp)
{
perror("open error");
return -1;
}
// 组包
sprintf(buf, "%04d:%02d:%02d", year, month, day);
// 写入文件
fputs(buf, fp);
return 0;
}
// 组包
//sprintf(buf, "%04d:%02d:%02d", year, month, day);
// 写入文件
//fputs(buf, fp);
//使用fprintf格式化写入文件
fprintf(fp, "%04d:%02d:%02d", year, month, day);
// 关闭文件
fclose(fp);
3.2 Reading files
- Header file:
#include <stdio.h>
- Define function:
int fscanf(FILE * stream, const char * format, ...);
- Function: Read the string from the file specified by
stream
, and convert and format the data according to the parameterformat
string. - Parameter:
stream:
Opened file
format:
String format, usage is the same asscanf()
- Return value:
Success: number of parameters, number of successfully converted values
Failure:- 1
Example:Usefscanf
to unpack file data
scanf("%d:%d:%d", &year, &month, &day);
sscanf(buf, "%d:%d:%d", &year, &month, &day);
fscanf(fp, "%d:%d:%d", &year, &month, &day);
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE* fp = NULL;
fp = fopen("fprintf.txt", "r"); // 2022:12:02
if (!fp)
{
perror("open error");
return -1;
}
int year = 0, month = 0, day = 0;
// 使用fscanf进行数据拆包
fscanf(fp, "%d:%d:%d", &year, &month, &day);
printf("%d-%d-%d", year, month, day);
// 关闭文件
fclose(fp);
return 0;
}
3.3 Intensive training: file version sorting
Write10
random numbers into abc.txt
, and then sort the random numbers in the abc.txt
file Write after
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define CALC_NUM 10 // 要生成1~3位的整数个数
#define FILE_PATH "abc.txt" // 文件路径
int main()
{
// 设置随机种子,并写入数据
FILE* fp = open_file("w");
srand(time(NULL));
for (int i = 0; i < CALC_NUM; i++)
{
// 产生随机数1~300
int num = rand() % 300 + 1;
// 格式化后写入
fprintf(fp, "%d\n", num);
}
// 关闭文件
close_file(fp);
// 读取文件中写入的随机数,并保存到数组中
int num = 0;
int nums[10] = {
0 };
int n = sizeof(nums) / sizeof(nums[0]);
fp = open_file("r");
for (int i = 0; i < n; i++)
{
// 格式化读取字符串
fscanf(fp, "%d", &num);
// 将随机数保存到数组中
nums[i] = num;
}
close_file(fp);
// 对nums数组元素进行排序
for (int i = 0; i < n - 1; i++) //比较的轮数
{
// 因为每次比较的次数都要减1,刚好i每次加1,所以每一轮比较的次数就是n-1-i
for (int j = 0; j < n - 1 - i; j++) // 每一轮比较的次数
{
if (nums[j] > nums[j + 1]) // 交换位置
{
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
// 再将排好序的nums数组写入到abc.txt文件
fp = open_file("w");
for (int i = 0; i < n; i++)
{
// 将nums每个元素进行组包
fprintf(fp, "%d\n", nums[i]);
}
close_file(fp);
return 0;
}
4) Read and write files fread and fwrite according to blocks
4.1 Write files
- Header file:
#include <stdio.h>
- Define function:
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
- Function: Write content to the file in the form of data blocks
- Parameter:
ptr:
The address to be written to file data
size:
size_t
is of typeunsigned int
. This parameter specifies the file to be written to. The block data size of the content
nmemb:
The number of blocks written to the file, the total size of the written file data is:size * nmemb
stream:
The open file pointer - Return value:
Success: The number of blocks actually successfully written to the file data. This value is equal to Failed:nmemb
0
Example:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct _std
{
int age;
char name[16];
}STD;
int main()
{
int cont = 0;
STD buf[3] = {
{
20, "cdtaogang"}, {
21, "laoli"}, {
22, "laozhao"} };
FILE* fp = fopen("fwrite.txt", "w");
// fwrite 第二个参数写1 ,是为了返回值刚好是写入文件的字节数,这也是个技巧
cont = fwrite(buf, 1, sizeof(buf), fp);
// cont = fwrite(buf, sizeof(buf), 1, fp);
// 验证返回值是否等于字节数
if (cont == sizeof(buf))
{
printf("cont == sizeof(buf) == %d", cont); // 60 (int:4 + char name[16]:16)*3
}
return 0;
}
4.2 Reading files
- Header file:
#include <stdio.h>
- Define function:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
- Function: Read content from the file in the form of data blocks
- Parameter:
ptr:
The memory space to store the read data
size:
size_t
is of typeunsigned int
. This parameter specifies the read The block data size of the file content
nmemb:
The number of blocks to read the file, the total size of the read file data is:size * nmemb
stream:
The open file pointer - Return value:
Success: The number of blocks that actually successfully read the content, if this value is smaller thannmemb
, but larger than0
, indicating that the end of the file is read.
failed:0
Example 1:Read the structure size one by one from the structure array
#pragma once
typedef struct _std
{
int age;
char name[16];
}STD;
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include "type.h"
int main()
{
// 定义结构体数组
STD buf[3];
// 全部设置为0
memset(buf, 0, sizeof(buf));
FILE* fp = NULL;
fp = fopen("fwrite.txt", "r");
if (!fp)
{
perror("open error");
return -1;
}
int cont = 0;
// 从结构体数组中,读取一个一个结构体大小
for (int i = 0; i < 3; i++)
{
cont = fread(&buf[i], 1, sizeof(STD), fp);
printf("cont=%d\n", cont);
printf("%d %s\n", buf[i].age, buf[i].name);
}
return 0;
}
输出结果
cont=20
20 cdtaogang
cont=20
21 laoli
cont=20
22 laozhao
Example 2:Read the entire structure array size at once
int main()
{
// 定义结构体数组
STD buf[3];
// 全部设置为0
memset(buf, 0, sizeof(buf));
FILE* fp = NULL;
fp = fopen("fwrite.txt", "r");
if (!fp)
{
perror("open error");
return -1;
}
int cont = 0;
// 一次性读完整个结构体数组大小
fread(buf, 1, sizeof(buf), fp);
for (int i = 0; i < 3; i++)
{
printf("%d %s\n", buf[i].age, buf[i].name);
}
return 0;
}
输出结果
20 cdtaogang
21 laoli
22 laozhao
4.3 Intensive training: large file copy
Implement copying of large binary files
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define BUFFER_SIZE 1024 * 64
int main()
{
printf("Start Copy\n");
// 拷贝的源地址
char* src_file = "a.mp4";
// 拷贝的目标地址
char* dst_file = "b.mp4";
// 以 可读 + 二进制 方式打开文件
// r 表示可读打开方式
// 打开方式后添加 b , 表示以二进制形式打开
FILE* p_src = fopen(src_file, "rb");
// 如果打开失败 , 直接返回
if (p_src == NULL) {
printf("src_file open failed");
return 0;
}
// 以 可写 + 二进制 方式打开文件
// w 表示可写打开方式
// 打开方式后添加 b , 表示以二进制形式打开
FILE* p_dst = fopen(dst_file, "wb");
// 如果打开失败 , 直接返回
if (NULL == p_dst) {
printf("dst_file open failed");
return 0;
}
// 为缓冲区内存申请堆内存
char* buffer = malloc(BUFFER_SIZE);
// 判定文件指针是否指向文件末尾
// 如果指向末尾 , 说明该文件
while (!feof(p_src)) {
// 读取源文件数据到 buffer 缓冲区, 读取 buffer_size 个字节
// 如果没有那么多字节 , 将读取的字节数返回
int res = fread(buffer, 1, BUFFER_SIZE, p_src);
// 将读取到缓冲区中的数据写出到目标文件中
fwrite(buffer, 1, res, p_dst);
}
// 释放缓冲区内存
free(buffer);
// 关闭源文件
fclose(p_src);
// 关闭目标文件
fclose(p_dst);
printf("Copy Success");
return 0;
}