C语言文件操作(笔记)(详细)

20 篇文章 5 订阅

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+”以“写入/更新”方式打开文件,相当于wr+叠加的效果。既可以读取也可以写入,也就是随意更新文件。如果文件不存在,那么创建一个新文件;如果文件存在,那么清空文件内容(相当于删除原文件,再创建一个新文件)。
“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 会存放错误代码.

下列是较特别的使用方式:

  1. 欲将读写位置移动到文件开头时:fseek(FILE *stream, 0, SEEK_SET);
  2. 欲将读写位置移动到文件尾时: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

  • 10
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值