• 【文件操作的重难点详解】


    今天向大家分享的是文件操作中文件的顺序读写以及随机读写的一些重难点问题。

     dd7e7e85b4ca4919a1b7af3e0b8cc339.gif

     

    目录

    1 文件的顺序读写

     1.1字符输出函数(fputc)&&字符输入函数(fgetc)

     1.2文本行输出函数(fputs)&&文本行输入函数(fgets)

     1.3格式化输出函数(fprintf)&&格式化输入函数(fscanf)

     1.4  扩展:

     1.5 二进制输出函数(fread)&&二进制输入函数(fwrite)

    2 文件的随机读写

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

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

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


     

     

    1 文件的顺序读写

     

    f2442f9d5e1f4bf9a48a52407193711d.png

     1.1字符输出函数(fputc)&&字符输入函数(fgetc)

     

    int fputc( int c, FILE *stream );

    写入一个字符:

    1. int main()
    2. {
    3. FILE* pf = fopen("text.txt", "w");
    4. if (pf == NULL)
    5. {
    6. printf("%s\n", strerror(errno));
    7. return 0;
    8. }
    9. else//写入文件
    10. {
    11. fputc('b', pf);
    12. fputc('i', pf);
    13. fputc('t', pf);
    14. }
    15. fclose(pf);
    16. pf = NULL;
    17. return 0;
    18. }

    其中打开文件用了fopen函数,关闭文件用了fclose函数.刚开始文件中并没有text.txt文件,由于fopen函数中第二个参数为"w"(具体可以看后面补充的图),所以它会自动建立了一个新文件,并用fputc函数将字符'b' 'i' 't'写入到了该文件夹中。

    62f04db98d094952bb471f4a1e61c99d.png

     双击打开后里面存放的是bit

    cd91ec9dc3f547d18da41b06bc349127.png

     该函数的作用是一次将一个字符写入到新建立的文件夹中。

    补充图:

    c241f043532a4c6b93daec981f7cc4ee.png

    读取一个字符:

    int fgetc( FILE *stream );

    1. int main()
    2. {
    3. FILE* pf = fopen("text.txt", "r");
    4. if (pf == NULL)
    5. {
    6. printf("%s\n", strerror(errno));
    7. return 0;
    8. }
    9. else//读取文件
    10. {
    11. printf("%c", fgetc(pf));
    12. printf("%c", fgetc(pf));
    13. printf("%c", fgetc(pf));
    14. }
    15. fclose(pf);
    16. ps = NULL;
    17. return 0;
    18. }

    由于刚才建立了文件夹text.txt,所以一个fgetc函数会将文件夹中一个字符读取出来:

    4e403834881641fbbb8b8c5ac5484617.png

     

    在这儿我们还得了解一些常识:

    1. 从键盘输入&&输出到屏幕中键盘&&屏幕都是外部设备。
    2. 键盘是标准输入设备,屏幕是标准输出设备。
    3. 任何c程序,在默认编译好之后,运行时都会打开3个输入输出流:stdin(标准输入) stdout(标准输出) stderr(标准错误)

    所以我们可以用fgetc&&fputc在键盘上输入信息以及在屏幕上打印信息:

    bdfb6532225042d5ad2c300efbcf8abc.png

     

     1.2文本行输出函数(fputs)&&文本行输入函数(fgets)

    写入一行字符:

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

     

    1. int main()
    2. {
    3. FILE* pf = fopen("text.txt", "w");
    4. if (pf == NULL)
    5. {
    6. printf("%s\n", strerror(errno));
    7. return 0;
    8. }
    9. //写入文件
    10. fputs("hello\n", pf);
    11. fputs("world", pf);
    12. fclose(pf);
    13. pf = NULL;
    14. return 0;
    15. }

    与fputc函数不同的是,该函数一次能写入一个字符串的数据到新建立的文件夹中:

    c721b88b11b2499ab9240e5402d1b505.png

    读取一行字符:

    char *fgets( char *string, int n, FILE *stream );

     

    1. int main()
    2. {
    3. FILE* pf = fopen("text.txt", "r");
    4. char buf[100]={0};
    5. if (pf == NULL)
    6. {
    7. printf("%s\n", strerror(errno));
    8. return 0;
    9. }
    10. //读取文件
    11. fgets(buf, 100, pf);
    12. puts(buf);
    13. fgets(buf, 100, pf);
    14. puts(buf);
    15. fclose(pf);
    16. pf = NULL;
    17. return 0;
    18. }

    这里定义了一个buf数组,将pf指向文件中的字符串拷贝到buf数组中:

    c6b0642c63264d11b0dd0dcc13e338bf.png

    用stdin&&stdout来从键盘上输入一行字符以及从屏幕上打印一行字符:

    1. int main()
    2. {
    3. char buf[100] = { 0 };
    4. fgets(buf, 100, stdin);
    5. fputs(buf, stdout);
    6. //gets(buf);
    7. //puts(buf);
    8. return 0;

    上述fgets和fputs与gets和puts效果差不多。

    1.3格式化输出函数(fprintf)&&格式化输入函数(fscanf)

    格式化输出函数(向文件中写入信息):

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

    1. struct stu
    2. {
    3. char name[10];
    4. char sex[5];
    5. int age;
    6. double weight;
    7. };
    8. int main()
    9. {
    10. struct stu s = { "lisi","男",18,60.0 };
    11. FILE* pf = fopen("text.txt", "w");
    12. if (pf == NULL)
    13. {
    14. printf("%s\n", strerror(errno));
    15. return 0;
    16. }
    17. fprintf(pf, "%s %s %d %lf", s.name, s.sex, s.age, s.weight);//向文件中输出信息
    18. fclose(pf);
    19. pf = NULL;
    20. return 0;
    21. }

     从代码中可以看到:我们将s进行了初始化,想将该内容拷贝到text.txt文件夹中:

    7509de4e5cd0417f9e8589e759180902.png

     代码执行后可以明显发现文件夹中已经成功拷贝。

    格式化输入函数(从文件中读取信息):

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

     

    1. struct stu
    2. {
    3. char name[10];
    4. char sex[5];
    5. int age;
    6. double weight;
    7. };
    8. int main()
    9. {
    10. struct stu s = { 0 };
    11. FILE* pf = fopen("text.txt", "r");
    12. if (pf == NULL)
    13. {
    14. printf("%s\n", strerror(errno));
    15. return 0;
    16. }
    17. fscanf(pf, "%s %s %d %lf", s.name, s.sex, &(s.age), &(s.weight));//从文件中获得信息
    18. printf("%s %s %d %lf", s.name, s.sex, s.age, s.weight);
    19. fclose(pf);
    20. pf = NULL;
    21. return 0;
    22. }

    代码中我们对s的内容初始化为0,代码执行后将文件夹中的内容拷贝到了s中:

    13bbee6ab7fc4786b72356cf6ed3cb9d.png

     我们还可以用stdin&&stdout来从键盘输入数据以及从屏幕上打印数据:b306e170c80d4253abf1ec5593ca0859.png

     1.4  扩展:

     int sprintf( char *buffer, const char *format [, argument] ... );

    int sscanf( const char *buffer, const char *format [, argument ] ... );

     

    1. int main()
    2. {
    3. struct stu s1 = { "lisi","男",18,60 };
    4. struct stu s2 = { 0 };
    5. char buf[100] = { 0 };
    6. //把格式化的数据转换成字符串存储到buf
    7. sprintf(buf, "%s %s %d %lf", s1.name, s1.sex, s1.age, s1.weight);
    8. printf("%s\n", buf);
    9. //从buf中读取格式化的数据到s2中
    10. sscanf(buf, "%s %s %d %lf", s2.name, s2.sex, &(s2.age), &(s2.weight));
    11. printf("%s %s %d %lf", s2.name, s2.sex, s2.age, s2.weight);
    12. return 0;
    13. }

    总结:

    1. scanf/printf:是针对标准输入流/标准输出流的格式化输入/输出语句。
    2. fscanf/fprintf:是针对所有输入流/所有输出流的格式化输入/输出语句 。
    3. sscanf/sprintf:sscanf是从字符串中读取格式化数据,sprintf是把格式化数据输出成(存储到)字符串。

     1.5 二进制输出函数(fread)&&二进制输入函数(fwrite)

    二进制输出函数:

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

     

    1. typedef struct stu
    2. {
    3. char name[20];
    4. int age;
    5. double weight;
    6. }stu;
    7. int main()
    8. {
    9. FILE* pf = fopen("text.txt", "wb");
    10. if (pf ==NULL)
    11. {
    12. printf("%s\n", strerror(errno));
    13. }
    14. stu s[2] = { {"zhangsan",18,60},{"lisi",19,65} };
    15. fwrite(s, sizeof(stu), 2, pf);
    16. fclose(pf);
    17. pf = NULL;
    18. return 0;
    19. }

    当我们查看文件里面的内容时:

    f2c2a8e5805c46f0bd15884294bb1584.png

     有的符号我们认识,但有的符号却很奇怪,为什么呢?

    由于我们写入的时二进制的形式,所以有些符号不认识很正常,但是当我们以二进制的形式读取时就不会出现这种奇怪的符号了。

    二进制输入函数:

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

     

     

    1. typedef struct stu
    2. {
    3. char name[20];
    4. int age;
    5. double weight;
    6. }stu;
    7. int main()
    8. {
    9. FILE* pf = fopen("text.txt", "rb");
    10. if (pf == NULL)
    11. {
    12. printf("%s\n", strerror(errno));
    13. return 0;
    14. }
    15. stu s[2] = { 0 };
    16. fread(s, sizeof(stu), 2, pf);
    17. printf("%s %d %lf\n%s %d %lf", s[0].name, s[0].age, s[0].weight, s[1].name, s[1].age, s[1].weight);
    18. fclose(pf);
    19. pf = NULL;
    20. return 0;
    21. }

     当读取信息时就会读取正常的信息:

    4f8f596a753e488d8701bd96c75f15ce.png

     

    2 文件的随机读写

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

     

     

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

     刚开始的时候文件中存放的是abcdef:

    2c241619dceb4f598421f205627c201a.png

     

    1. int main()
    2. {
    3. FILE* pf = fopen("text.txt", "r");
    4. if (pf == NULL)
    5. {
    6. printf("%s\n", strerror(errno));
    7. return 0;
    8. }
    9. fseek(pf, 2, SEEK_CUR);
    10. int ch = fgetc(pf);
    11. printf("%c\n", ch);
    12. fclose(pf);
    13. pf = NULL;
    14. return 0;
    15. }

    e61787ad9e104a39a8a8af9652770f8a.png

     

     在这之前我们还得了解一下origin:

    SEEK_CUR

    Current position of file pointer

    SEEK_END

    End of file

    SEEK_SET

    Beginning of file

     至于为什么打印的是c:从a开始偏移2个字符得到的就是c.此时pf指向下一个字符(也就是d):

    120999e40a064c62af0feb0663b8be8a.png

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

     

    long ftell( FILE *stream );

     5229702bab3f4183bd3d303cc24744fd.png

     这个函数的用法很简单,就不多说了。

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

    void rewind( FILE *stream );

     

    这个函数的作用是让pf指向文件字符的开头:

    2d5669cd4c53416b9074a5c498bdd3ac.png

     好了,今天的分享就到这里了。希望老铁们能够指出文章中的错误所在,酸Q。

    8be4b6d0c842470ca3d35c73cf9455a4.png

     

     

  • 相关阅读:
    数据标注工具 doccano | 文本分类(Text Classification)
    Linux:使用ssl加密网站为https
    基于C++QT5的学生信息综合管理系统
    C#,人工智能,深度学习,OpenCV开发,入门教程——Visual Studio 2022,OpenCvSharp环境搭建与可视化
    解决pip下载速度过慢的问题
    pytorch的模型保存加载和继续训练
    Linux的简单认识和云主机的使用教程
    Vue 指令整理
    【Oracle】Oracle系列之九--Oracle常用函数
    Synchronized面试题
  • 原文地址:https://blog.csdn.net/m0_68872612/article/details/125810844