• C语言中的文件操作


    目录

    一、什么是文件

    1、程序文件

    2、数据文件

     3、文件名

    二、文件的打开和关闭

    1、文件指针

    2、文件的打开和关闭

    三、文件的顺序读写

    四、文件的随机读写

    1、fseek

     2、ftell

    3、rewind

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

     六、文件读取结束的判定

    七、文件缓冲区


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

    一、什么是文件

    磁盘上的文件是文件。

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

    1、程序文件

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

    2、数据文件

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

     3、文件名

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

    例如:

    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
    2. #include
    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
    2. #include
    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

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

    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

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

    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

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

    void rewind ( FILE * stream );

    使用举例:

    1. #include
    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
    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
    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. }

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

  • 相关阅读:
    从零开始学习调用百度地图网页API:三、鼠标点击绘图功能
    [附源码]SSM计算机毕业设计“云味坊”购物网站JAVA
    vite跨域proxy设置与开发、生产环境的接口配置,接口在生产环境下,还能使用proxy代理地址吗
    9.05 Day46---Vue文件的组成、Vue语法 & 指令、MVVM设计模式、Vue组件的生命周期和钩子函数
    Linux -- 进程间通信之匿名管道
    prettytable:一款像数据库一样可完美格式化输出的 Python 库
    CAT1 4G+以太网开发板腾讯云手机微信小程序显示温度和下发控制
    MemArts :高效解决存算分离架构中数据访问的组件
    SpringBoot整合SpringSession实现分布式登录
    Git常见命令与使用,从0到1学会使用Git
  • 原文地址:https://blog.csdn.net/lang_965/article/details/125825123