C语言之文件操作
文件是什么
在操作系统中,为了统一对各种硬件的操作,简化接口,不同的硬件设备也都被看成一个文件。对这些文件的操作,等同于对磁盘上普通文件的操作。例如:
- 通常把显示器称为标准输出文件,printf 就是向这个文件输出数据;
- 通常把键盘称为标准输入文件,scanf 就是从这个文件读取数据。
文件 | 硬件设备 |
---|---|
stdin | 标准输入文件,一般指键盘;scanf()、getchar() 等函数默认从 stdin 获取输入。 |
stdout | 标准输出文件,一般指显示器;printf()、putchar() 等函数默认向 stdout 输出数据。 |
stderr | 标准错误文件,一般指显示器;perror() 等函数默认向 stderr 输出数据(后续会讲到)。 |
stdprn | 标准打印文件,一般指打印机。 |
打开文件和关闭文件
fopen()函数
fopen() 会获取文件信息,包括文件名、文件状态、当前读写位置等,并将这些信息保存到一个 FILE 类型的结构体变量中,然后将该变量的地址返回。如果打开失败,将会返回一个NULL指针。
fopen()函数的打开方式:
控制读写权限的字符串(必须指明) | |
---|---|
打开方式 | 说明 |
“r” | 以“只读”方式打开文件。只允许读取,不允许写入。文件必须存在,否则打开失败。 |
“w” | 以“写入”方式打开文件。如果文件不存在,那么创建一个新文件;如果文件存在,那么清空文件内容(相当于删除原文件,再创建一个新文件)。 |
“a” | 以“追加”方式打开文件。如果文件不存在,那么创建一个新文件;如果文件存在,那么将写入的数据追加到文件的末尾(文件原有的内容保留)。 |
“r+” | 以“读写”方式打开文件。既可以读取也可以写入,也就是随意更新文件。文件必须存在,否则打开失败。 |
“w+” | 以“写入/更新”方式打开文件,相当于w 和r+ 叠加的效果。既可以读取也可以写入,也就是随意更新文件。如果文件不存在,那么创建一个新文件;如果文件存在,那么清空文件内容(相当于删除原文件,再创建一个新文件)。 |
“a+” | 以“追加/更新”方式打开文件,相当于a和r+叠加的效果。既可以读取也可以写入,也就是随意更新文件。如果文件不存在,那么创建一个新文件;如果文件存在,那么将写入的数据追加到文件的末尾(文件原有的内容保留)。 |
控制读写方式的字符串(可以不写) | |
打开方式 | 说明 |
“t” | 文本文件。如果不写,默认为"t" 。 |
“b” | 二进制文件。 |
fopen()的文件路径:
fopen可以使用相对路径和绝对路径。
相对路径:文件相对当前代码文件所在文件夹的路径。
绝对路径:文件在计算机中存储的绝对路径。
例子,:
int main()
{
FILE* fp = fopen("test.txt", "r"); //这里使用相对路径,代码和文件在同一个文件夹下,只读方式打开
if(fp==NULL) //如果打开失败,结束程序
return 0;
char ch = fscanf("%c"); //读取一个字符并打印
printf("%c\n", ch);
fclose(fp); //操作完成之后结束程序
return 0;
}
fclose()函数
使用fclose()函数关闭文件。参数为文件指针。
文件的读写
读文件
fscanf()函数–指定类型读文件
功能:从一个流中执行格式化输入
表头文件:#include<stdio.h>
函数原型:int fscanf(FILE *stream, char *format[,argument…]);
返回值:成功时返回转换的字节数,失败时返回一个负数
format为指定要读入的类型,如%d,%c,%s等
例子:
int main()
{
FILE* fp = fopen("test.txt", "r");
if(!fp)
return 0;
char str[20];
int flag=0;
flag = fscanf(fp, "%s", str); //从文件中读取一个字符串
if(flag)
printf("%s", str);
}
fgets()函数–读取一个字符串
表头文件 include<stdio.h>
定义函数 char * fgets(char * s,int size,FILE * stream);
函数说明 fgets()用来从参数stream所指的文件内读入字符并存到参数s所指的内存空间,直到出现换行字符、读到文件尾或是已读了size-1个字符为止,最后会加上NULL作为字符串结束。
返回值 gets()若成功则返回s指针,返回NULL则表示有错误发生。
例子:
int main()
{
char str[50];
FILE* fp = fopen("test.txt", "r");
if(!fp)
return 0;
fgets(str, 30, fp);
puts(str);
return 0;
}
fgetc()函数–读取一个字符
表头文件 include<stdio.h>
定义函数 int fgetc(FILE * stream);
函数说明 fgetc()从参数stream所指的文件中读取一个字符。若读到文件尾而无数据时便返回EOF。
返回值 getc()会返回读取到的字符,若返回EOF则表示到了文件尾。
例子:
main()
{
FILE *fp;
int ch;
fp = fopen("exist", "r");
while((ch = fgetc(fp)) != EOF) //当读到文件末尾退出循环
printf("%c", ch);
fclose(fp);
}
fread()函数–读取数据块(二进制方式)
头文件:#include <stdio.h>
定义函数size_t fread(void *buffer, size_t size, size_t count, FILE * stream);
size_t是unsigne int的别名
buffer为接收数据的地址,size为一个单元的大小,count为单元个数,stream为文件流。
fread()函数每次从stream中最多读取count个单元,每个单元大小为size个字节,将读取的数据放到buffer;文件流的位置指针后移 size * count 字节。
返回值:返回实际读取的单元个数。如果小于count,则可能文件结束或读取出错;可以用ferror()检测是否读取出错,用feof()函数检测是否到达文件结尾。如果size或count为0,则返回0。
例子:
int main()
{
char str[10];
FILE* fp = fopen("test.txt", "r");
if (!fp)
return 0;
fread(str, sizeof(char), 10, fp);
puts(str);
fclose(fp);
}
写入文件
fputc()函数–写入字符
表头文件 #include<stdio.h>
定义函数 int fputc(int c,FILE * stream);
函数说明 fputc 会将参数c 转为unsigned char 后写入参数stream 指定的文件中。
返回值 fputc()会返回写入成功的字符,即参数c。若返回EOF则代表写入失败。
例子:
int main()
{
char ch = 'a';
FILE* fp = fopen("test.txt", "w");
if (!fp)
return 0;
fputc(ch, fp);
fclose(fp);
}
fputs()函数–写入字符串
表头文件 #include<stdio.h>
定义函数 int fputs(const char * s,FILE * stream);
函数说明 fputs()用来将参数s所指的字符串写入到参数stream所指的文件内。
返回值 若成功则返回写出的字符个数,返回EOF则表示有错误发生。
例子:
int main()
{
char str[20] = "hello world";
FILE* fp = fopen("test.txt", "w");
if (!fp)
return 0;
fputs(str, fp);
fclose(fp);
}
fwrite()函数–写入数据块(二进制方式)
表头文件 #include<stdio.h>
定义函数 size_t fwrite(const void * ptr,size_t size,size_t nmemb,FILE * stream);
函数说明 fwrite()用来将数据写入文件流中。参数stream为已打开的文件指针,参数ptr 指向欲写入的数据地址,总共写入的字符数以参数size*nmemb来决定。Fwrite()会返回实际写入的nmemb数目。
返回值 返回实际写入的nmemb数目。
例子:
int main()
{
char Cities[][10] = {
"BeiJINg", "ShangHai", "Guangzhou", "Shenzhen" };
FILE* fp = fopen("test.txt", "w");
if (!fp)
return 0;
fwrite(Cities, sizeof(Cities), 1, fp);
fclose(fp);
}
fprintf()函数–指定类型写文件
表头文件:#include<stdio.h>
函数原型:int fprintf(FILE *stream, char *format[, argument,…]);
返回值:成功时返回转换的字节数,失败时返回一个负数
例子:
int main()
{
FILE* fp = fopen("test.txt", "w");
if (!fp)
return 0;
char str[20] = "hello world";
fprintf(fp, "%s", str);
fclose(fp);
}
文件定位函数–随机读写文件
rewind()函数–将位置指针移动到文件开头
表头文件:#include<stdio.h>
函数原型:void rewind(FILE *stream)
例子:
int main()
{
FILE* fp = fopen("test.txt", "a+");
if (!fp)
return 0;
char str1[10], str2[10];
fscanf(fp, "%s", str1);
rewind(fp); //将文件指针移动到开头
fscanf(fp,"%s", str2);
puts(str1);
puts(str2);
fclose(fp);
}
文件内容:
运行结果:
fseek()函数–将位置指针移动到任意位置
表头文件:#include <stdio.h>
定义函数:int fseek(FILE * stream, long offset, int whence);
返回值:当调用成功时则返回0, 若有错误则返回-1, errno 会存放错误代码.
下列是较特别的使用方式:
- 欲将读写位置移动到文件开头时:fseek(FILE *stream, 0, SEEK_SET);
- 欲将读写位置移动到文件尾时:fseek(FILE *stream, 0, 0SEEK_END);
SEEK_SET表示文件开头,0表示偏移量为0
0SEEK_END表示文件结尾,0表示偏移量为0
例子:
int main()
{
FILE* fp = fopen("test.txt", "a+");
if (!fp)
return 0;
char ch;
int i;
for (i = 0; i < 5; i++) //不移动指针,读五个字符
{
fscanf(fp, "%c", &ch);
printf("%c ", ch);
}
printf("\n");
for (i = 0; i < 5; i++) //移动指针,读五个字符
{
fscanf(fp, "%c", &ch);
fseek(fp, 5, SEEK_SET); //将位置指针移动到相对开头位置的第五位
printf("%c ", ch);
}
fclose(fp);
}
文件内容:
运行结果:
文件操作应用
文件复制
这里使用了文件读写函数来实现文件复制,代码如下:
int main()
{
FILE* bin = fopen("bin.png", "r");
FILE* des = fopen("des.png", "w+"); //des原本不存在,打开方式使用w+会自动创建文件des.png
if (!bin || !des)
return 0;
int op;
while (!feof(bin)) //判断是否读到文件末尾
{
fread(&op, 1, 1, bin); //从bin中读取一个字节存放到op中
fwrite(&op, 1, 1, des); //将op中的内容写入到des
}
fclose(bin);
fclose(des);
}
这里的feof()函数是判断文件指针是否到达文件末尾,如果到达文件末尾,则返回EOF
转载:https://blog.csdn.net/qq_52698632/article/details/117046789