前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C语言文件读写操作(详解)

C语言文件读写操作(详解)

作者头像
全栈程序员站长
发布于 2022-09-05 03:00:48
发布于 2022-09-05 03:00:48
1.9K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

数据流和缓冲区是什么?文件类型和文件存取方式都有啥?

  • 数据流 就C程序而言,从程序移进,移出字节,这种字节流就叫做流。程序与数据的交互是以流的形式进行的。进行C语言文件的读写时,都会先进行“打开文件”操作,这个操作就是在打开数据流,而“关闭文件”操作就是关闭数据流。
  • 缓冲区 在程序执行时,所提供的额外内存,可用来暂时存放准备执行的数据。它的设置是为了提高存取效率,因为内存的存取速度比磁盘驱动器快得多。 当使用标准I/O函数(包含在头文件stdio.h中)时,系统会自动设置缓冲区,并通过数据流来读写文件。当进行文件读取时,是先打开数据流,将磁盘上的文件信息拷贝到缓冲区内,然后程序再从缓冲区中读取所需数据。事实上,当写入文件时,并不会马上写入磁盘中,而是先写入缓冲区,只有在缓冲区已满或“关闭文件”时,才会将数据写入磁盘。
  • 文件类型 文本文件和二进制文件: 文本文件是以字符编码的方式进行保存的。 二进制文件将内存中的数据原封不动的进行保存,适用于非字符为主的数据。其实,所有的数据都可以算是二进制文件。二进制文件的优点在于存取速度快,占用空间小。
  • 文件存取方式 顺序存取方式和随机存取方式: 顺序存取就是从上往下,一笔一笔读取文件的内容。写入数据时,将数据附加在文件的末尾。这种存取方式常用于文本文件。 随机存取方式多半以二进制文件为主。它会以一个完整的单位来进行数据的读取和写入,通常以结构为单位。

什么是文件呢?

文件是一段数据的集合,这些数据可以是有规则的,也可以是无序的集合。在stdio.h有一个非常重要的东西,文件指针,每个文件都会在内存中开辟一块空间,用于存放文件的相关信息,这些信息保存在一个结构体中: struct _iobuf { char *_ptr; //指向buffer中第一个未读的字节 int _cnt; //记录剩余的未读字节的个数 char *_base;//文件的缓冲 int _flag;//打开文件的属性 int _file;//获取文件描述 int _charbuf;//单字节的缓冲,即缓冲大小仅为1个字节 int _bufsiz;//记录这个缓冲大小 char *_tmpfname;//临时文件名 }; typedef struct _iobuf FILE; FILE是一个数据结构,用于访问一个流。每个流都会对应一个FILE结构体。

C语言文件操作函数详解

C语言中没有输入输出语句,所有的输入输出功能都用 ANSI C提供的一组标准库函数来实现。文件操作标准库函数有:

  • 文件的打开 fopen():打开文件
  • 文件的关闭 fclose():关闭文件
  • 文件的读写 fgetc():读取一个字符 fputc():写入一个字符 fgets():读取一个字符串 fputs():写入一个字符串 fprintf():写入格式化数据 fscanf():格式化读取数据 fread():读取数据 fwrite():写入数据
  • 文件状态检查 feof():文件是否结束 ferror():文件读/写是否出错 clearerr():清除文件错误标志 ftell():文件指针的当前位置
  • 文件指针定位 rewind():把文件指针移到开始处 fseek():重定位文件指针

参数解释: “r”:以只读的形式打开文本文件(不存在则出错) “w”:以只写的形式打开文本文件(若不存在则新建,反之,则从文件起始位置写,覆盖原内容) “a”:以追加的形式打开文本文件(若不存在,则新建;反之,在原文件后追加) “r+”:以读写的形式打开文本文件(读时,从头开始;写时,新数据只覆盖所占的空间) “wb”:以只写的形式打开二进制文件 “rb”:以只读的形式打开二进制文件 “ab”:以追加的形式打开一个二进制文件 “rb+”:以读写的形式打开二进制文件。 “w+”:首先建立一个新文件,进行写操作,然后从头开始读(若文件存在,原内容将全部消失) “a+”:功能与”a”相同。只是在文件尾部追加数据后,可以从头开始读 “wb+”:功能与”w+”相同。只是在读写时,可以由位置函数设置读和写的起始位置 “ab+”:功能与”a+”相同。只是在文件尾部追加数据之后,可以由位置函数设置开始读的起始位置

打开文件 FILE *fopen( const char *filename, const char *mode );

  • filename:文件的路径
  • mode:打开模式

例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int main()
{ 
   
    FILE* f;
    f = fopen("file.txt", "w");
    if (f != NULL)
    { 
   
        fputs("fopen example", f);
        fclose(f);
        f=NULL;
    }
    return 0;
}

注意:

  • 文件是否打开成功
  • 关闭文件
  • 文件指针置空

关闭文件 函数原型:int fclose( FILE *stream );

  • stream:流

例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if(fclose(f)!=0) 
{ 
   
	printf("File cannot be closed/n"); 
	exit(1); 
} 
else
{ 
   
    printf("File is now closed/n"); 
}

读取字符 int fgetc ( FILE * stream );

  • stream:流

例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
int main ()
{ 
   
  FILE * pFile;
  int c;
  int n = 0;
  pFile = fopen ("D:\\myfile.txt", "r");
  if (pFile == NULL) perror ("Error opening file"); // 打开失败
  else
  { 
   
    while (c != EOF)
    { 
   
      c = fgetc (pFile); // 获取一个字符
      if (c == '$') n++; // 统计美元符号 '$' 在文件中出现的次数
    }
    fclose (pFile); // 一定记得要关闭文件
    printf ("The file contains %d dollar sign characters ($).\n",n);
  }
  return 0;
}

写入字符 int fputc( int c, FILE *stream );

  • c:要写入的字符
  • stream:流

例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    char ch;
    FILE* pf = fopen("file.txt", "w");
    if (pf == NULL)
    { 
   
        perror("error opening file");
        exit(0);
    }
    ch = getchar();
    while (ch != '$')
    { 
   
        fputc(ch, pf);
        ch = getchar();
    }
    fclose(pf);

读取字符串 char * fgets ( char * str, int num, FILE * stream );

  • str:将读取到的内容复制到的目标字符串
  • num:一次读取的大小
  • stream:流

例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    char buf[10] = { 
    0 };
    FILE *pf = fopen("file.txt", "r");
    if (pf == NULL)
    { 
   
        perror("open file for reading");
        exit(0);
    }
    fgets(buf, 9, stdin);
    printf("%s", buf);
    fclose(pf);

写入字符串 int fputs( const char *string, FILE *stream );

  • string:要写入的字符串
  • stream:一次读取的大小

例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    char buf[10] = { 
    0 };
    FILE *pf = fopen("file.txt", "r");
    if (pf == NULL)
    { 
   
        perror("open file for reading");
        exit(0);
    }
    fgets(buf, 9, stdin);
    fputs(buf, stdout);
    fclose(pf);

读取数据块 size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

  • ptr:目标内存块
  • size:一次读取的字节大小
  • count:一次读取多少个 size
  • stream:流

例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <string.h>
 
int main()
{ 
   
    FILE *pFile = fopen("file.txt", "rb");
    if (pFile == NULL) 
    { 
   
        perror ("Error opening file");
        return 0;
    }
    char buf[100] = { 
    0 };
    while (!feof(pFile)) //没有到文件末尾
    { 
   
        memset(buf, 0, sizeof(buf));
        size_t len = fread(buf, sizeof(char), sizeof(buf), pFile);
        printf("buf: %s, len: %d\n", buf, len);
    }
    fclose(pFile);
}

写入数据块 size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream ); 同理,简单好理解,就不详细阐述了。

文件指针重定位 int fseek ( FILE * stream, long int offset, int origin );

  • stream:流
  • offset:相对应 origin 位置处的偏移量,单位为字节
  • origin:指针的位置 #define SEEK_CUR 1 // 当前位置 #define SEEK_END 2 // 末尾 #define SEEK_SET 0 // 开头

获取指针位置 long int ftell ( FILE * stream );

  • stream:流

获取文件大小 例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
long n;
fseek(pf,0,SEEK_END);
n=ftell(pf);

文件指针移到开始处 void rewind( FILE *stream );

  • stream:流

清除文件错误标志 void clearerr( FILE *stream );

  • stream:流

文件流是否读到了文件尾 int feof( FILE *stream );

  • stream:流

重命名文件 int rename ( const char * oldname, const char * newname );

  • oldname:原名
  • newname:新名

删除文件 int remove ( const char * filename );

  • filename:文件的路径

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/137033.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年6月2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
做了一夜动画,就为让大家更好的理解Vue3的Composition Api
这个文章其实很简单, 只要能说明composition的好处,就是极好的,我们用一个非常简单的万金油场景,比如我们有一个非常简单的to do list
前端达人
2021/01/27
3530
做了一夜动画,就为让大家更好的理解Vue3的Composition Api
vue3-Composition-API实操
我们都知道composition api是可以和options api一起使用、友好相处的,比如下面的示例:
刘嘿哈
2022/10/25
4710
学习 Vue 3 全家桶 - Vite 和 Composition API
如果在一个页面里有多个功能,那就需要在 data 和 methods 里分别进行配置。但这样的话,数据和方法相关的代码会写在一起,在组件代码行数多了后就不好维护。可以使用 Composition API 的逻辑来拆分代码,把一个功能相关的数据和方法都维护在一起。
Cellinlab
2023/05/17
4290
学习 Vue 3 全家桶 - Vite 和 Composition API
Vue3 TypeScript 使用教程 - 实战 Vue3 element-plus 开发「待办清单」
本文完整版:《Vue3 TypeScript 使用教程 - 实战 Vue3 element-plus 开发「待办清单」》
蒋川@卡拉云
2022/05/27
2.1K0
Vue3 TypeScript 使用教程 - 实战 Vue3 element-plus 开发「待办清单」
使用 Vue 3 与 TypeScript 构建 Web 应用: Todo
引言 界面: Vue.js 3 JavaScript 超集: TypeScript 包管理器: pnpm 前端工程化/打包: Vite 路由: Vue Router 状态管理: Pinia CSS 预处理器: Less 代码格式化: Prettier 代码质量: ESLint 预览
yiyun
2023/07/17
1.2K0
使用 Vue 3 与 TypeScript 构建 Web 应用: Todo
Vue3实战系列:结合 Ant-Design-of-Vue 实践 Composition API
但是事物总有它的两面性,前端知识更新的很快,利好勤奋好学的同学。计算机行业的迭代速度很快,前端在计算机领域里,算是前浪被拍在沙滩上比较快的。
程序员十三
2020/10/23
1.3K0
Vue3 Composition API 之 setup 函数
在说 Vue3 之前,我们先看看 Vue2 项目中是如何编写逻辑代码的, 新建一个组件
青年码农
2022/12/13
4690
Vue3 Composition API 之 setup 函数
Vue3.0 七大亮点是什么??
在vue3中,增加了静态标记PatchFlag。在创建vnode的时候,会根据vnode的内容是否可以变化,为其添加静态标记PatchFlag。diff的时候,只会比较有PatchFlag的节点。PatchFlag是有类型的,比如一个可变化文本节点,会将其添加PatchFlag枚举值为TEXT的静态标记。这样在diff的时候,只需比对文本内容。需要比对的内容更少了。PatchFlag还有动态class、动态style、动态属性、动态key属性等枚举值。
逆锋起笔
2021/06/11
1K0
译文:Vue3 Composition API 是如何取代 Vue Mixins 的?
原文:https://css-tricks.com/how-the-Vue-composition-api-replaces-vue-mixins/
前端开发博客
2020/11/04
3.5K0
将Ts往Vue3中再整合一下
以上内容整理自“Young村长”的B站视频,单单去学习Ts语法总是没有在实践中用用学的快,推荐你们多像Young村长学习呀,老铁们。
前端小鑫同学
2022/12/26
4440
将Ts往Vue3中再整合一下
Vue3 Composition API教程及示例
Vue引入了Composition API(基于功能的API)作为当前基于Option的API的补充。该API将随Vue 3一起发布,但是现在您可以通过将Vue 3 Composition API添加到您的Vue 2应用程序中来进行尝试。
前端知否
2020/03/23
4.9K0
Vue3 Composition API教程及示例
Vue 3中令人激动的新功能:Composition API
在上一篇文章中,我们了解了Vue 3将带来的性能提升。我们已经知道在Vue新的主要版本中编写的应用程序会有很好的性能,但性能并不是最重要的部分。对我们开发者来说,最重要的是新版本将如何影响我们编写代码的方式。
前端开发博客
2020/11/04
7310
Vue3开发最佳实践和实用技巧(上)
上面我们发现 number 类型竟然书写了两次,我们可以单独抽离成一个类型方便复用
PHP开发工程师
2022/08/20
1.5K0
打包 Composition API、Vue3
到目前为止 Vue 为我们提供了两种开发组件的 API 风格,选项式 API 和组合式 API。组合式 API 可以由我们导入不同的 API 函数来描述组件的逻辑,在 SFC 组件中通常还会在 script 标签显示标注setup来使用。
前端小鑫同学
2022/12/26
6150
Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?
Composition API 可以说是Vue3最大的特点,那么为什么要推出Composition Api,解决了什么问题?
@超人
2021/03/18
1K0
Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?
vue 随记(3):“新时代”的姿势
•性能上:最多比vue2 快2倍•静态标记提升•proxy取代defineProperty•tree shaking:按需编译打包代码•composition api :类似hook的编码风格•支持typescript:面向未来目前的代码 98% 以上使用 TypeScript 编写。如果你还没有学习 TypeScript,请尽快学习,否则可能看不懂源码。另外有件事情说出来可能会让你非常惊讶,Vue 3 的源代码完全没有使用 class 关键字!(只在测试代码和示例代码里用到了 class 关键字)•custom renderer api:自定义渲染
一粒小麦
2020/07/21
6840
vue2.0教程
或者使用CDN <script src="https://unpkg.com/vue/dist/vue.js"></script>
lilugirl
2019/05/28
8690
vue2.0教程
关于 vue3 + typescript 项目中常用的知识点汇总
在实际项目开发中,常常会遇到这么一个场景,某一个路由是不需要渲染到侧边栏导航上的,此时我们可以给该路由添加一个hidden属性来实现。
前端达人
2021/07/19
1.6K0
关于 vue3 + typescript 项目中常用的知识点汇总
Vue3.0 不畏惧祖传代码的 Composition API
昨晚写这篇文章的时候,隔壁在聚餐,几位女生欢聚一堂,整个楼层充满了欢声笑语的味道,就好像早上刷牙刷一半就跑去吃了个鸡蛋。
用户1890129
2020/12/16
5560
Vue3.x相对于Vue2.x的变化
ps: 上图中,一种颜色代表一个功能,我们可以看到Options API的功能代码比较分散;Composition API则可以将同一个功能的逻辑,组织在一个函数内部,利于维护。
conanma
2021/11/03
8930
推荐阅读
相关推荐
做了一夜动画,就为让大家更好的理解Vue3的Composition Api
更多 >
LV.5
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档