1 C语言中文件操作大概分几步
-
使用fopen打开文件,选择打开模式
-
使用文件相关api对文件进行读、写操作
-
使用完成后释放文件指针关闭文件
2 文件打开方式
文件打开方式我们分为文本文件和二进制文件的打开方式,
文本文件打开方式有以下几种:
-
r:打开一个已经存在的文本文件,只能从文本文件中读取数据。如果指定文件不存在,程序就会出错。
-
w:打开一个文件文件,只能将数据写入文件。如果已经存在该文件名的文件,文件被重写:如果不存在,则以该文件名建立新的文件。
-
a:以附加方式打开文件,将数据写入文件的尾部。如果文件不存在,创建新的文件用于写入。
-
r+:打开一个已经存在的文本文件,可以从中读取数据,也可以写入数据。
-
w+:打开一个已经存在的文本文件,可以读取数据,也可以写入数据,若文件不存在,则自动建立一个新文件,接收写入的数据;若文件存在,则删去旧文件,建立一个同名新文件,接收写入的数据。
-
a+:打开一个已经存在的文本文件,可以读取数据,也可以从当前文件的尾部追加写入数据。当文件不存在时,创建新的文件用于文件尾写入。
二进制文件打开方式
-
rb:打开一个已经存在的二进制文件,只能从二进制文件中读取数据。如果指定文件不存在,程序就会出错。
-
wb:打开一个二制制文件,只能将数据写入文件。如果已经存在该文件名的文件,文件被重写;如果不存在,则以该文件名建立新的文件。
-
ab:打开一个已经存在的二进制文件,只能从当前文件的尾部追加写入数据。如果文件不存在,创建新的文件用于写入。
-
rb+:打开一个已经存在的二进制文件,可以从中读取数据,也可以写入数据。
-
wb+:打开一个已经存在的二进制文件,可以读取数据,也可以写入数据,若文件不存在,则自动建立一个新文件,接收写入的数据;若文件存在,则删去旧文件,建立个同名新文件,接收写入的数据。
-
ab+:打开一个已经存在的文本文件,可以读取数据,也可以从当前文件的尾部追加写入数据。当文件不存在时,创建新的文件用于文件尾写入。
其中,
r(read)表示读
w(write)表示写
a(append)表示添加
b(binary)表示二进制文件
3 文件读写
3.1 字符读写方式
这里准备了一个test.txt的文本文件,内容截图如下
3.1.1 读文件
首先创建一个fileName的文件指针,while循环中使用feof()对文件读取末尾进行判断,如果未到文件末尾则使用putchar()将字符一个个显示在屏幕上,最后使用fclose()关闭文件,释放资源。
char *fileName = "E:\\test.txt";
FILE *fp=fopen(fileName,"a+");
if (fp == NULL) {
printf("文件打开失败\n");
exit(0);
}
else {
printf("文件打开成功\n");
}
//读文件
while (!feof(fp))
{
char ch=fgetc(fp);
putchar(ch);
}
fclose(fileName);
运行截图如下:
3.1.2 写文件
下面代码是将字符串info写入到文件,while循环中通过指针逐个取字符,最后将info写到文件中。
char *info = "hello world";
fputc('\n', fp);
while (*info !='\0')
{
fputc(*info,fp);
info++;
}
运行结果截图:
3.2 按照字符串方式读写
上面按字符方式读取,如果内容是英文的,那么读取是没问题的,但如果内容是中文的,那么读取就是乱码的(有兴趣的可以自己试下,将test.txt的文件内容换成中文进行读取,或者将info换成中文写入),所以我们需要以字符串方式来读取。
字符串方式的读写比单个字符读取效率更高。
我们使用字符串方式读写来实现一个文件的复制,用到的函数有fgets(),fputs()。
FILE *origin, *dest;
char *originName = "E:\\test.txt";
char *destName = "E:\\test2.txt";
//源文件
origin = fopen(originName, "r");
if (origin == NULL) {
printf("文件不存在");
exit(0);
}
//目标文件
dest = fopen(destName, "w+");
if (dest==NULL)
{
printf("打开文件失败");
exit(0);
}
//开始复制文件内容
char buf[1024];
char *content= fgets(buf, sizeof(buf), origin);
while (fgets(buf, sizeof(buf), origin) !=NULL)
{
fputs(buf,dest);
}
//关闭文件
fclose(origin);
fclose(dest);
运行结果如图:
3.3 二进制文件读写
读写二进制如果使用字符货字符串方式读取,肯定是不行的,这种方式肯定会出现乱码的情况,这时候我们就应该使用二进制的方式读写。
这里我们使用一张图片作为案例,将图片a.png复制一份儿,重新命名为b.png
FILE *a_file, *b_file;
char buffer[1024];
size_t bytes_read;
// 打开a.png文件
a_file = fopen("E\\a.png", "rb");
if (a_file == NULL) {
printf("无法打开a.png文件!\n");
return 1;
}
// 创建b.png文件
b_file = fopen("E:\\b.png", "wb");
if (b_file == NULL) {
printf("无法创建b.png文件!\n");
return 1;
}
// 从a.png读取数据并写入b.png
while ((bytes_read = fread(buffer, 1, sizeof(buffer), a_file)) > 0) {
fwrite(buffer, 1, bytes_read, b_file);
}
// 关闭文件
fclose(a_file);
fclose(b_file);
yu
运行结果:
4 常见的文件操作函数说明
4.1 fopen()
函数原型:FILE *fopen(const char *filename, const char *mode)
函数说明:打开文件并返回文件指针,文件指针用于后续的文件读写操作。
参数说明:
- filename:要打开的文件名。
- mode:打开文件的模式,包括读、写、追加等模式。
返回值:文件指针,如果文件打开失败,则返回NULL。
4.2 fclose()
函数原型:int fclose(FILE *stream)
函数说明:关闭文件,释放文件指针。
参数说明:stream为要关闭的文件指针。
返回值:成功返回0,失败返回EOF。
4.3 fgets()
函数原型:char *fgets(char *str, int n, FILE *stream)
函数说明:从文件中读取一行数据,返回一个字符串。
参数说明:
- str:读取的数据存放的缓冲区。
- n:读取的最大字符数。
- stream:要读取数据的文件指针。
返回值:成功返回读取的字符串,失败返回NULL。
4.4 fputc()
函数原型:int fputc(int c, FILE *stream)
函数说明:向文件中写入一个字符。
参数说明:
- c:要写入的字符。
- stream:要写入数据的文件指针。
返回值:成功返回写入的字符,失败返回EOF。
4.5 fputs()
函数原型:int fputs(const char *str, FILE *stream)
函数说明:向文件中写入一个字符串。
参数说明:
- str:要写入的字符串。
- stream:要写入数据的文件指针。
返回值:成功返回非负数,失败返回EOF。
4.6 fread()
函数原型:size_t fread(void *ptr, size_t size, size_t count, FILE *stream)
函数说明:从文件中读取数据到缓冲区中。
参数说明:
- ptr:存放读取数据的缓冲区。
- size:每个数据项的字节数。
- count:要读取的数据项数。
- stream:要读取数据的文件指针。
返回值:成功返回读取的数据项数,失败返回0。
4.7 fwrite()
函数原型:size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream)
函数说明:将缓冲区的数据写入文件中。
参数说明:
- ptr:要写入文件的数据。
- size:每个数据项的字节数。
- count:要写入的数据项数。
- stream:要写入数据的文件指针。
返回值:成功返回写入的数据项数,失败返回0。
4.8 fseek()
函数原型:int fseek(FILE *stream, long offset, int whence)
函数说明:设置文件指针的位置。
参数说明:
- stream:要设置位置的文件指针。
- offset:相对于whence的偏移量。
- whence:设置偏移量的基准位置,包括文件开头、文件末尾等。
返回值:成功返回0,失败返回非0值。
4.9 ftell()
函数原型:long ftell(FILE *stream)
函数说明:获取文件指针的当前位置。
参数说明:stream为要获取位置的文件指针。
返回值:返回文件指针的当前位置。
4.10 rewind()
函数原型:void rewind(FILE *stream)
函数说明:将文件指针回到文件开头。
参数说明:stream为要回到开头的文件指针。
4.11 remove()
函数原型:int remove(const char *filename)
函数说明:删除文件。
参数说明:filename为要删除的文件名。
返回值:成功返回0,失败返回非0值。
4.12 rename()
函数原型:int rename(const char *oldname, const char *newname)
函数说明:重命名文件。
参数说明:
-
oldname:要重命名的文件名。
-
newname:新的文件名。
返回值:成功返回0,失败返回非0值。
4.13 feof()
函数原型:int feof(FILE *stream)
函数说明:判断文件是否已经结束。
参数说明:stream为要判断的文件指针。
返回值:如果文件已经结束,返回非0值,否则返回0。
4.14 perror()
函数原型:void perror(const char *s)
函数说明:输出文件操作错误信息。
参数说明:s为要输出的错误信息前缀。
返回值:无。
5 总结
后续使用过程中,碰到了再继续完善