经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C 语言 » 查看文章
C语言文件操作详解
来源:jb51  时间:2021/10/11 13:06:24  对本文有异议

一、什么是文件

在程序设计中,我们一般谈的文件有两种:程序文件、数据文件。

程序文件:

包括源程序文件(后缀为.c ),目标文件( windows环境后缀为.obj ) ,可执行程序( windows环境后缀为.exe )。

数据文件:

文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件

或者输出内容的文件。

数据文件又分为”文本文件“和”二级制文件

二进制文件:数据在内存中以二进制的形式存储,如果不加转换的输出到外存,这种文件我们是看不懂的是一堆乱七八糟的符号,只有电脑才可以读懂。

文本文件:如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式

存储的文件就是文本文件。这种文件我们是看得懂的,例如我们在记事本看到的”字“”字母“”数字“,这样的文件就是文本文件。

二、文件缓冲区

ANSIC采用”缓冲文件系统“来处理数据文件,系统会为每一个正在使用的文件开辟一块”文件缓冲区“。当程序从内存向磁盘输出数据时,会将数据先送到输出缓冲区中,等输出缓冲区满了之后,才将数据一起送到磁盘;当程序从磁盘向内存读数据时,数据会先被送到输入缓冲区,等输入缓冲区满了之后,才将数据一起送到磁盘;另外程序结束时,缓冲区的内容也会被送到内存或磁盘。

三、文件指针

每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的

名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是

由系统声明的,取名FILE。

该结构体声明如下:

  1. struct _iobuf {
  2. char *_ptr;
  3. int _cnt;
  4. char *_base;
  5. int _flag;
  6. int _file;
  7. int _charbuf;
  8. int _bufsiz;
  9. char *_tmpfname;
  10. };
  11. typedef struct _iobuf FILE;

每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,我们就可以通

过创建一个FILE的指针来维护这个FILE结构的变量。

  1. FILE* pf;//文件指针变量

四、文件的打开和关闭。

文件的打开用fopen函数,文件的关闭用fclose函数。

它们的原型如下:

FILE * fopen ( const char * filename, const char * mode );

int fclose ( FILE * stream );

filenname:这个参数填的是文件名

mode:这个参数代表要对文件进行的操作

stream:这个参数代表指向要关闭的文件的指针。

文件的操作方式有:

“r”(只读):程序从一个文本文件读入数据,如果指定文件不存在会出错 。

“w”(只写):程序向一个文本文件输出数据,如果指定文件不存在会建立一个新的文件。

“a”(追加): 向文本文件尾添加数据 ,如果指定文件不存在会出错

“rb”(只读): 程序从一个文件读入数据,只不过这个文件是二进制文件,如果指定文件不存在会出错 。

“wb”(只写): 程序向一个文件输出数据,只不过这个文件是二进制文件 ,如果指定文件不存在会建立一个新的文件

“ab”(追加): 向一个二进制文件尾添加数据,,如果指定文件不存在会出错

“r+”(读写): 为了读和写,这个文件是文本文件,如果文件不存在会出错

“w+”(读写): 为了读和写,如果文件不存在会建立一个新的文件

“a+”(读写): 打开一个文件,在文件尾进行读写 ,如果文件不存在会建立一个新的文件

“rb+”(读写) :为了读和写,打开一个二进制文件 ,如果文件不存在会出错

“wb+”(读写) :为了读和写一个二进制文件 ,如果文件不存在会建立一个新的文件

“ab+”(读写):在 二进制文件尾进行读和写 如果文件不存在会建立一个新的文件

文件的读写函数有(这些函数是顺序读写):

字符输入函数:fgetc
字符输出函数:fputc
文本行输入函数:fgets
文本行输出函数:fputs
格式化输入函数:fscanf
格式化输出函数:fprintf
二进制输入:fread
二进制输出:fwrite

下面我们用代码来体会:

  1. int main()
  2. {
  3. //打开文件
  4. FILE* pf = fopen("data.txt", "r");
  5. if (pf == NULL)
  6. {
  7. //如果没有读到,返回错误信息。
  8. perror("fopen");
  9. return -1;
  10. }
  11. //读文件
  12. //
  13. //关闭文件
  14. fclose(pf);
  15. pf = NULL;
  16. return 0;
  17. }

我们对data.txt,进行”r“(读)操作,因为当前文件夹下没有创建这个文件,所以出错。

现在我们在当前目录下,创建一个diata.txt文件夹,并输入字符"abcd",使用fgetc函数来读取数据,这个函数的作用是读取一个字符后,指针往下一个字符走。

  1. int main()
  2. {
  3. //打开文件
  4. FILE* pf = fopen("data.txt", "r");
  5. if (pf == NULL)
  6. {
  7. perror("fopen");
  8. return -1;
  9. }
  10. //读文件
  11. char ch = fgetc(pf);
  12. printf("%c\n", ch);
  13. ch = fgetc(pf);
  14. printf("%c\n", ch);
  15. //关闭文件
  16. fclose(pf);
  17. pf = NULL;
  18. return 0;
  19. }

结果为:

这是因为刚刚开始时,pf指针首先指向首字符”a“,读完字符”a“后,pf指针就往下一个字符走,指向了字符”b“,读完”b“后,pf指针继续往下一个字符走,指向了字符”c“。

现在使用fgetc函数来读取数据,这个函数的作用是读取一个字符串

  1. int main()
  2. {
  3. //打开文件
  4. FILE* pf = fopen("data.txt", "r");
  5. if (pf == NULL)
  6. {
  7. perror("fopen");
  8. return -1;
  9. }
  10. //读文件
  11. char arr[20] = { 0 };
  12. fgets(arr, 20, pf);
  13. printf("%s", arr);
  14. //关闭文件
  15. fclose(pf);
  16. pf = NULL;
  17. return 0;
  18. }

结果是:

这个代码的意思是从pf指向的那个文件读取20个字符,存到数组arr中,我们知道文件只有4个字符,所以当文件不够要被读取字符数,程序就只会把文件中的内容读完,而不会报错。

下面我们进行”w“操作,并分别使用fputc、fputs函数

fputc函数

  1. int main()
  2. {
  3. FILE* pf = fopen("test.txt", "w");
  4. if (NULL == pf)
  5. {
  6. perror("fopen");
  7. return -1;
  8. }
  9. //写文件
  10. fputc('b', pf);
  11. fputc('i', pf);
  12. fputc('t', pf);
  13. //关闭文件
  14. fclose(pf);
  15. pf = NULL;
  16. return 0;
  17. }

我们向test.txt文件进行写操作,如果我们对一个文件进行写操作,如果这个文件存在,且有内容,写操作会将文件的内容销毁,重新写入目前我们要写的内容。因为我们当前文件夹下没有创建这样的文件,所以程序自动帮我们创建,我们使用fputs函数,这个函数的作用是向文件写入一个字符,在这些代码中,我们分别写了”b“、”i“、”t“这几个字符

fputs函数

  1. int main()
  2. {
  3. FILE* pf = fopen("test.txt", "w");
  4. if (NULL == pf)
  5. {
  6. perror("fopen");
  7. return -1;
  8. }
  9. //写文件
  10. //写一行数据
  11. fputs("hello world\n", pf);
  12. fputs("hello bit\n", pf);
  13. //关闭文件
  14. fclose(pf);
  15. pf = NULL;
  16. }

fputs函数的作用是向文件输出一个字符串。因为这个文件在之前已经创建,且有字符”bit“,现在我们重新进行写操作,字符”bit“会被销毁,重新写入hello world、hello bit这两个字符串。

fprintf函数

  1. struct S
  2. {
  3. int n;
  4. double d;
  5. };
  6. int main()
  7. {
  8. struct S s = { 100, 3.14 };
  9. FILE* pf = fopen("data.txt", "w");
  10. if (NULL == pf)
  11. {
  12. perror("fopen");
  13. return -1;
  14. }
  15. //写文件
  16. fprintf(pf, "%d %lf", s.n, s.d);
  17. //关闭文件
  18. fclose(pf);
  19. pf = NULL;
  20. }

fprintf函数的作用是向pf指向的那个文件输出格式化字符(所谓的格式化就是类似于代码中"%d %lf"的格式),所以这个程序会向文件输出”100“和”3.140000“.

fscanf函数

  1. struct S
  2. {
  3. int n;
  4. double d;
  5. };
  6. int main()
  7. {
  8. struct S s = { 0 };
  9. FILE* pf = fopen("data.txt", "r");
  10. if (NULL == pf)
  11. {
  12. perror("fopen");
  13. return -1;
  14. }
  15. //读文件
  16. fscanf(pf, "%d %lf", &(s.n), &(s.d));
  17. printf("%d %lf\n", s.n, s.d);
  18. //关闭文件
  19. fclose(pf);
  20. pf = NULL;
  21. }

fscanf函数的作用是从文件中读取格式化数据,存到内存中,由是一个代码只,文件中有”100“和”3.140000“这两个数据,所以这个程序会将这两个数据读到结构体变量s中.

最后两个函数使用方法与fgetc fputc fgets fputs函数类似,我就不示例了,同学们自己来试试吧!!!!!

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注w3xue的更多内容!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号