• C语言第三十六弹---文件操作(中)


    个人主页: 熬夜学编程的小林

    💗系列专栏: 【C语言详解】 【数据结构详解】

    文件操作

    1、文件的顺序读写

    1.1、顺序读写函数介绍

    1.1.1、fgetc 与 fputc

    1.1.2、fgets 与 fputs

    1.1.3、fscanf 与 fprintf

    1.1.4、fread 与 fwrite

    1.2、对比一组函数

    总结


    1、文件的顺序读写

    1.1、顺序读写函数介绍

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

    上面说的适用于所有输入流⼀般指适用于标准输入流和其他输入流(如文件输入流)所有输出流⼀般指适用于标准输出流和其他输出流(如文件输出流)

    1.1.1、fgetc 与 fputc

    int fputc ( int character, FILE * stream );

    将字符写入流。
    将字符写入流并推进位置指示器。

    字符被写在流的内部位置指示器指示的位置,然后自动前进一个。

    举个例子:

    1. #include <stdio.h>
    2. int main()
    3. {
    4. //打开文件
    5. FILE* pf = fopen("test.txt", "w");
    6. //文件操作
    7. if (pf == NULL)
    8. {
    9. perror("fopen");
    10. return 1;
    11. }
    12. //将字符写入文件
    13. fputc('a', pf);
    14. fputc('b', pf);
    15. fputc('c', pf);
    16. fputc('d', pf);
    17. //关闭文件
    18. fclose(pf);
    19. pf = NULL;
    20. return 0;
    21. }

    VS执行此代码之后不会输出内容,需要去找到对应文件验证。 

    int fgetc ( FILE * stream );

    从流中获取字符。
    返回指定流的内部文件位置指示器当前指向的字符。然后,内部文件位置指示器将前进到下一个字符。

    如果流在调用时位于文件末尾,则该函数将返回 EOF 并设置流的文件末尾指示符 (feof)。

    如果发生读取错误,该函数将返回 EOF 并设置流的错误指示器 (ferror)。

    fgetc 和 getc 是等效的,只是 getc 在某些库中可以作为宏实现。

    举个例子:

    1. #include <stdio.h>
    2. int main()
    3. {
    4. //打开文件
    5. FILE* pf = fopen("test.txt", "r");
    6. //文件操作
    7. if (pf == NULL)
    8. {
    9. perror("fopen");
    10. return 1;
    11. }
    12. //pf流中读取数据
    13. int ch = fgetc(pf);
    14. printf("%c ", ch);
    15. ch = fgetc(pf);
    16. printf("%c ", ch);
    17. ch = fgetc(pf);
    18. printf("%c ", ch);
    19. ch = fgetc(pf);
    20. printf("%c ", ch);
    21. //关闭文件
    22. fclose(pf);
    23. pf = NULL;
    24. return 0;
    25. }

    输出结果与对应文件内容比较如下图:

    1.1.2、fgets 与 fputs

    int fputs ( const char * str, FILE * stream );

    将字符串写入流。
    将 str 指向的 C 字符串写入流。

    该函数从指定的地址 (str) 开始复制,直到到达终止 null 字符 ('0')。此终止 null 字符不会复制到流中。

    请注意,fputs 与 puts 的不同之处不仅在于可以指定目标流,而且 fputs 不会写入其他字符,而 puts 会自动在末尾附加换行符。

    举个例子:

    1. #include <stdio.h>
    2. int main()
    3. {
    4. //打开文件
    5. FILE* pf = fopen("test1.txt", "w");
    6. //文件操作
    7. if (pf == NULL)
    8. {
    9. perror("fopen");
    10. return 1;
    11. }
    12. //将字符串写入文件
    13. fputs("abcdef", pf);
    14. //关闭文件
    15. fclose(pf);
    16. pf = NULL;
    17. return 0;
    18. }

    执行该代码之后的文件结果如下图: 

    1. char * fgets ( char * str, int num, FILE * stream );
    2. //str为接受数据的地址

    从流中获取字符串。
    从流中读取字符,并将它们作为 C 字符串存储到 str 中,直到读取 (num-1) 个字符或到达换行符或文件末尾,以先到者为准。

    换行符使 fgets 停止读取,但它被函数视为有效字符,并包含在复制到 str 的字符串中。

    终止 null 字符会自动追加到复制到 str 的字符之后。

    请注意,fgets 与 gets 有很大不同:fgets 不仅接受 stream 参数,还允许指定 str 的最大大小,并在字符串中包含任何结束换行符。

    1. #include <stdio.h>
    2. int main()
    3. {
    4. //打开文件
    5. FILE* pf = fopen("test1.txt", "r");
    6. //文件操作
    7. if (pf == NULL)
    8. {
    9. perror("fopen");
    10. return 1;
    11. }
    12. char arr[100] = { 0 };
    13. //将文件中读取字符串
    14. fgets(arr, 5, pf);
    15. printf("%s\n", arr);
    16. //关闭文件
    17. fclose(pf);
    18. pf = NULL;
    19. return 0;
    20. }

    测试结果如下图: 

    1.1.3、fscanf 与 fprintf

    int fprintf ( FILE * stream, const char * format, ... );

    将格式化的数据写入流。
    将按格式指向的 C 字符串写入流。如果 format 包含格式说明符(以 % 开头的子序列),则格式后面的附加参数将被格式化并插入到生成的字符串中,以替换它们各自的说明符。

    在 format 参数之后,该函数至少需要与 format 指定的其他参数一样多的附加参数。

    举个例子:

    1. #include <stdio.h>
    2. struct S
    3. {
    4. float f;
    5. char c;
    6. int n;
    7. };
    8. int main()
    9. {
    10. struct S s = { 5.2f,'c',52 };//结构体初始化
    11. //打开文件
    12. FILE* pf = fopen("test1.txt", "w");
    13. //文件操作
    14. if (pf == NULL)
    15. {
    16. perror("fopen");
    17. return 1;
    18. }
    19. //写文件
    20. fprintf(pf, "%f-%c-%d", s.f, s.c, s.n);
    21. //关闭文件
    22. fclose(pf);
    23. pf = NULL;
    24. return 0;
    25. }

    代码测试:

    int fscanf ( FILE * stream, const char * format, ... );

    从流中读取格式化的数据。
    从流中读取数据,并根据参数格式将数据存储到其他参数所指向的位置。

    附加参数应指向已分配的对象,该对象由格式字符串中的相应格式说明符指定。

    举个例子:

    1. #include <stdio.h>
    2. struct S
    3. {
    4. float f;
    5. char c;
    6. int n;
    7. };
    8. int main()
    9. {
    10. struct S s = { 0 };
    11. //打开文件
    12. FILE* pf = fopen("test1.txt", "r");
    13. //文件操作
    14. if (pf == NULL)
    15. {
    16. perror("fopen");
    17. return 1;
    18. }
    19. //读文件
    20. fscanf(pf, "%f-%c-%d", &(s.f), &(s.c), &(s.n));
    21. printf("%f-%c-%d\n", s.f, s.c, s.n);
    22. //关闭文件
    23. fclose(pf);
    24. pf = NULL;
    25. return 0;
    26. }

    测试代码: 

    1.1.4、fread 与 fwrite

    size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

    将数据块写入流中。
    从 ptr 指向的内存块写入一个 count 元素数组,每个元素的大小为 Bytes 字节。

    流的位置指示器按写入的总字节数前进。

    在内部,该函数将 ptr 指向的块解释为无符号字符类型的 (size*count) 元素数组,并按顺序将它们写入流式处理,就好像为每个字节调用了 fputc 一样。

    举个例子:

    1. #include <stdio.h>
    2. int main()
    3. {
    4. int arr[] = { 0,1,2,3,4,5,6,7,8,9 };
    5. //打开文件
    6. FILE* pf = fopen("data.txt", "wb");
    7. //文件操作
    8. if (pf == NULL)
    9. {
    10. perror("fopen");
    11. return 1;
    12. }
    13. //二进制写文件
    14. fwrite(arr, sizeof(arr[0]), sizeof(arr) / sizeof(arr[0]), pf);
    15. //关闭文件
    16. fclose(pf);
    17. pf = NULL;
    18. return 0;
    19. }

    测试代码: 

    size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

    从流中读取数据块。
    从流中读取 count 元素的数组,每个元素的大小为 bytes,并将它们存储在 ptr 指定的内存块中。

    流的位置指示器按读取的总字节数前进。

    如果成功,读取的总字节数为 (size*count)。

    举个例子:

    1. #include <stdio.h>
    2. int main()
    3. {
    4. int arr[10] = { 0 };
    5. //打开文件
    6. FILE* pf = fopen("data.txt", "rb");
    7. //文件操作
    8. if (pf == NULL)
    9. {
    10. perror("fopen");
    11. return 1;
    12. }
    13. //二进制写文件
    14. fread(arr, sizeof(arr[0]), sizeof(arr) / sizeof(arr[0]), pf);
    15. for (int i = 0; i < 10; i++)
    16. {
    17. printf("%d ", arr[i]);
    18. }
    19. //关闭文件
    20. fclose(pf);
    21. pf = NULL;
    22. return 0;
    23. }

    测试代码: 

    1.2、对比一组函数


    scanf / fscanf / sscanf

    1. int scanf ( const char * format, ... );
    2. //使用键盘输入信息
    3. int fscanf ( FILE * stream, const char * format, ... );
    4. //将stream中的信息写入后面格式化函数中
    5. int sscanf ( const char* s, const char * format, ... );
    6. //将字符串信息转化为格式化信息


    printf / fprintf / sprintf

    1. int printf ( const char * format, ... );
    2. //打印信息到屏幕
    3. int fprintf ( FILE * stream, const char * format, ... );
    4. //将后面格式化信息写到stream中
    5. int sprintf ( char * str, const char * format, ... );
    6. //将格式化数据转化为字符串数据

    总结


    本篇博客就结束啦,谢谢大家的观看,如果公主少年们有好的建议可以留言喔,谢谢大家啦!

  • 相关阅读:
    java中的try-with-resource语法
    四、Go中的条件判断和for循环
    MySQL必知必会-笔记 Part2
    Revit MEP 平面视图中(立管)怎么设置二维表达?
    11月19日绿健简报,星期六,农历十月廿六
    重置系统后出现 press F12 to clear the tpm press Esc to reject this chan
    被Linux之父骂醒?英伟达破天荒开源GPU内核驱动,网友:活久见
    Python基础 P6函数
    剑指offer——JZ77 按之字形顺序打印二叉树 解题思路与具体代码【C++】
    Burpsuite专业版安装步骤
  • 原文地址:https://blog.csdn.net/2201_75584283/article/details/136007549