0


C语言中的文件操作

为了防止通讯录程序退出时数据消失,我们必须要将数据持久化,把数据存放到磁盘、存放到数据库,使用文件可以直接将数据放在电脑的硬盘上。

一、什么是文件

磁盘上的文件是文件。

从文件功能分类:程序文件、数据文件。

1、程序文件

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

2、数据文件

数据文件是程序运行时需要从中读取数据的文件,或者输出内容的文件。

3、文件名

文件名即文件标识,包含:文件路径+文件名主干+文件后缀

例如:

  1. C:\数学建模\数学模型作业.docx

二、文件的打开和关闭

1、文件指针

被使用的文件在内存中开辟了文件信息区,存放文件的名字、状态、当前位置等信息,这些信息保存在结构体变量中,结构体类型取名FILE。

不同的C编译器的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结构的变量,并填充信息。

定义pf是一个指向FILE类型数据的指针变量,使pf指向某个文件的文件信息区,并访问文件。

2、文件的打开和关闭

编写程序时,打开文件的时候,返回一个FILE*指针变量指向该文件。

  1. //打开文件
  2. FILE* fopen(const char* filename, const char* mode);
  3. //关闭文件
  4. int fclose(FILE* stream);

mode代表文件的打开模式,打开方式如下:

代码展示:

  1. #include<errno.h>
  2. #include<string.h>
  3. int main()
  4. {
  5. FILE* pFile;
  6. pFile = fopen("myfile.txt", "w");//打开文件
  7. if (pFile == NULL)
  8. {
  9. printf("%s\n", strerror(errno));
  10. return 1;
  11. }
  12. //写(输出)文件
  13. fputs("fopen example", pFile);
  14. //关闭文件
  15. fclose(pFile);
  16. pFile = NULL;
  17. return 0;
  18. }

三、文件的顺序读写

功能函数名适用于字符输入函数fgetc所以输入流字符输出函数fputc所有输出流文本行输入函数fgets所有输入流文本行输出函数fputs所有输出流格式化输入函数fscanf所有输入流格式化输出函数fprintf所有输出流二进制输入fread文件二进制输出fwrite文件

文件的顺序读写库函数使用举例:

  1. #include<string.h>
  2. #include<errno.h>
  3. int main()
  4. {
  5. FILE* pf = fopen("test.txt", "w");
  6. if (pf = NULL)
  7. {
  8. printf("5s\n", strerror(errno));
  9. return 1;
  10. }
  11. //写文件
  12. char i = 0;
  13. for (i = 'a'; i <= 'z'; i++)
  14. {
  15. fputs(i, pf);
  16. }
  17. //关闭文件
  18. fclose(pf);
  19. pf = NULL;
  20. return 0;
  21. }
  22. //读一个字符
  23. int main()
  24. {
  25. FILE* pf = fopen("test.txt", "r");
  26. if (pf == NULL)
  27. {
  28. printf("%s\n", strerror(errno));
  29. return 1;
  30. }
  31. //读文件
  32. char ch = 0;
  33. while ((ch = fgetc(pf)) != EOF)
  34. {
  35. printf("%c\n", ch);
  36. }
  37. //关闭文件
  38. fclose(pf);
  39. pf = NULL;
  40. return 0;
  41. }
  42. //写一行数据
  43. int main()
  44. {
  45. FILE* pf = fopen("test.txt", "w");
  46. if (pf == NULL)
  47. {
  48. printf("%s\n", strerror(errno));
  49. return 1;
  50. }
  51. //写一行数据
  52. fputs("get money\n", pf);
  53. fputs("get meney\n", pf);
  54. //关闭文件
  55. fclose(pf);
  56. pf = NULL;
  57. return 0;
  58. }
  59. //读一行数据
  60. int main()
  61. {
  62. FILE* pf = fopen("test.txt", pf);
  63. if (pf == NULL)
  64. {
  65. perror("fopen");
  66. return 1;
  67. }
  68. char arr[20];
  69. fgets(arr, 20, pf);
  70. printf("%s\n", arr);
  71. //关闭文件
  72. fclose(pf);
  73. pf = NULL;
  74. return 0;
  75. }
  76. //格式化输入输出
  77. struct S
  78. {
  79. char arr[20];
  80. int age;
  81. float score;
  82. };
  83. struct S s = { 0 };
  84. int main()
  85. {
  86. FILE* pf = fopen("test.txt", "r");
  87. if(pf==NULL)
  88. {
  89. perror("fopen");
  90. return 1;
  91. }
  92. fscanf(pf, "%s %d %f", s.arr, &(s.age), &(s.score));
  93. fprintf(stdout, "%s %d %s", s.arr, s.age, s.score);
  94. fclose(pf);
  95. pf = NULL;
  96. return 0;
  97. }
  98. //以二进制形式输入输出
  99. int main()
  100. {
  101. struct S s = { 0 };
  102. FILE* pf = fopen("test.txt", "rb");
  103. if (pf = NULL)
  104. {
  105. perror(pf);
  106. return 1;
  107. }
  108. //二进制方式读
  109. fread(&s, sizeof(struct S), 1, pf);
  110. printf("%s %d %f\n", s.arr, s.age, s.score);
  111. fclose(pf);
  112. pf = NULL;
  113. return 0;
  114. }
  115. int main()
  116. {
  117. struct S s = { "sunlang",25,50.f };
  118. FILE* pf = fopen("test.txt", "wb");
  119. if (pf == NULL)
  120. {
  121. perror("fopen");
  122. return 1;
  123. }
  124. fwrite(&s, sizeof(struct S), 1, pf);
  125. fclose(pf);
  126. pf = NULL;
  127. return 0;
  128. }

scanf/fscanf/sscanf与printf/fprintf/sprintf的对比:

scanf是针对标准输入的格式化输入语句

printf是针对标准输出的格式化输出语句

fscanf是针对所有输入流的格式化输入语句

fprintf是针对所有输出流的格式化输出语句

sscanf是从一个字符串中转化出一个格式化的数据

sprinf是把一个格式化的数据转化成字符串

  1. //sscanf与sprintf的举例:
  2. struct S
  3. {
  4. char arr[10];
  5. int age;
  6. float score;
  7. };
  8. int main()
  9. {
  10. struct S s = { "zhangsan",20,55.5f };
  11. struct S tmp = { 0 };
  12. char a[100] = { 0 };
  13. //把s中的格式化数据转化成字符串放到a中
  14. sprintf(a, "%s %d %f", s.arr, s.age, s.score);
  15. //从字符串a中获取一个格式化的数据到tmp中
  16. sscnaf(a, "%s %d %f", tmp.arr, &(tmp.age), tmp.score);
  17. return 0;
  18. }

四、文件的随机读写

1、fseek

根据文件指针的位置和偏移量来定位文件指针

  1. int fseek ( FILE * stream, long int offset, int origin );

使用举例:

  1. int main()
  2. {
  3. FILE* pFile;
  4. pFile = fopen("example.txt", "wb");
  5. fputs("This is an apple.", pFile);
  6. fseek(pFile, 9, SEEK_SET);
  7. fputs("sam", pFile);
  8. fclose(pFile);
  9. return 0;
  10. }

2、ftell

返回文件指针相对于起始位置的偏移量

  1. long int ftell ( FILE * stream );

使用举例:

  1. int main()
  2. {
  3. FILE* pFile;
  4. long size;
  5. pFile = fopen("myfile.txt", "rb");
  6. if (pFile == NULL)
  7. {
  8. perror("Error opening file");
  9. }
  10. else
  11. {
  12. fseek(pFile, 0, SEEK_END);
  13. size = ftell(pFile);
  14. fclose(pFile);
  15. printf("Size of myfile.txt:%ld bytes.\n", size);
  16. }
  17. return 0;
  18. }

3、rewind

让文件指针的位置回到文件的起始位置

  1. void rewind ( FILE * stream );

使用举例:

  1. #include <stdio.h>
  2. int main ()
  3. {
  4. int n;
  5. FILE * pFile;
  6. char buffer [27];
  7. pFile = fopen ("myfile.txt","w+");
  8. for ( n='A' ; n<='Z' ; n++)
  9. fputc ( n, pFile);
  10. rewind (pFile);
  11. fread (buffer,1,26,pFile);
  12. fclose (pFile);
  13. buffer[26]='\0';
  14. puts (buffer);
  15. return 0;
  16. }

五、文本文件和二进制文件

二进制文件:数据在内存中以二进制的形式存储,不加转换地输出到外存

文本文件:需要在存储前转换,以ASCII字符的形式存储的文件

字符用ASCII形式存储,数值型数据用ASCII形式或二进制形式存储。

例子:

  1. int main()
  2. {
  3. int a = 10000;
  4. FILE* pf = fopen("text.txt", "wb");
  5. fwrite(&a, 4, 1, pf);
  6. fclose(pf);
  7. pf = NULL;
  8. return 0;
  9. }

六、文件读取结束的判定

feof函数:表示在文件读取结束的时候,文件结束的原因:是读取失败,还是遇到文件结尾。

判断文件读取是否结束:fgetc判断是否为EOF;fgets判断返回值是否小于实际要读的个数。

二进制文件读取结束判断:返回值是否小于实际要读的个数,fread判断返回值是否小于实际要读的个数。

案例说明:

判断文本文件读取结束:

  1. #include <stdlib.h>
  2. int main(void)
  3. {
  4. int c;
  5. FILE* fp = fopen("test.txt", "r");
  6. if (!fp) {
  7. perror("File opening failed");
  8. return EXIT_FAILURE;
  9. }
  10. while ((c = fgetc(fp)) != EOF)
  11. {
  12. putchar(c);
  13. }
  14. if (ferror(fp))
  15. puts("I/O error when reading");
  16. else if (feof(fp))
  17. puts("End of file reached successfully");
  18. fclose(fp);
  19. }

判断二进制文件读取结束:

  1. enum { SIZE = 5 };
  2. int main(void)
  3. {
  4. double a[SIZE] = { 1.,2.,3.,4.,5. };
  5. FILE* fp = fopen("test.bin", "wb");
  6. fwrite(a, sizeof * a, SIZE, fp);
  7. fclose(fp);
  8. double b[SIZE];
  9. fp = fopen("test.bin", "rb");
  10. size_t ret_code = fread(b, sizeof * b, SIZE, fp);
  11. if (ret_code == SIZE) {
  12. puts("Array read successfully, contents: ");
  13. for (int n = 0; n < SIZE; ++n) printf("%f ", b[n]);
  14. putchar('\n');
  15. }
  16. else {
  17. if (feof(fp))
  18. printf("Error reading test.bin: unexpected end of file\n");
  19. else if (ferror(fp)) {
  20. perror("Error reading test.bin");
  21. }
  22. }
  23. fclose(fp);
  24. }

七、文件缓冲区

因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件中操作结束时的时候关闭文件。

  1. #include <windows.h>
  2. int main()
  3. {
  4. FILE* pf = fopen("test.txt", "w");
  5. fputs("abcdef", pf);
  6. printf("睡眠10秒-已经写数据了,打开test.txt文件,发现文件没有内容\n");
  7. Sleep(10000);
  8. printf("刷新缓冲区\n");
  9. fflush(pf);
  10. printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n");
  11. Sleep(10000);
  12. fclose(pf);
  13. pf = NULL;
  14. return 0;
  15. }

本次分享到此结束,后续会有不断更新,不要忘记一键三连噢~

标签: 大数据 c语言

本文转载自: https://blog.csdn.net/lang_965/article/details/125825123
版权归原作者 发烧的CPU 所有, 如有侵权,请联系我们删除。

“C语言中的文件操作”的评论:

还没有评论