C语言,文件操作详解,C语言文件操作详解指南

马肤

温馨提示:这篇文章已超过467天没有更新,请注意相关的内容是否还可用!

摘要:,,本文详细介绍了C语言中的文件操作,涵盖了文件的打开、读写、关闭等基本操作。通过本文,读者可以了解到C语言中文件操作的基本流程和注意事项,包括文件指针的使用、文件读写函数的应用以及文件操作中的错误处理。本文还深入探讨了文件操作的细节和常见问题解决方案,帮助读者更好地掌握C语言文件操作技巧。

目录

什么是文件

文件的类型

文件操作

流的概念

标准流

文件操作的步骤

文件的打开与关闭 

fopen

fclose  

 文件的顺序读写

fgetc

fputc

fputs

fgets

 fscanf

fprintf

fwrite

fread

文件的随机读写

fseek

ftell

rewind

文件读取结束的判定


什么是文件

        文件是是计算机硬盘存储的数据的集合,它可以是文本文档,也可以是图片,程序等等。将数据存储进文件内可以很好的保存数据,方便程序员对文件的操作。

文件的类型

        一般根据存储数据类型的不同可以分为二进制文件和文本文件。数据在内存中是以二进制存储的,不加任何转换的输出就是二进制文件,如果要求数据在外存以ASCII码(美国信息交换标准代码)的形式显示就是文本文件。

需要注意的是,数值型数据在外存中既可以以二进制存储,也可以以ASCII值存储,字符型数据在外存中只能以ASCII值存储,而这两者在内存中都是以二进制存储的。

文件操作

流的概念

        我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输⼊输出 操作各不相同,为了⽅便程序员对各种设备进⾏⽅便的操作,我们抽象出了流的概念,我们可以把流 想象成流淌着字符的河。 C程序针对⽂件、画⾯、键盘等的数据输⼊输出操作都是通过流操作的。 ⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作。 

换句话说:流就是程序员与外部沟通的桥梁

        同样在对文件进行操作的时候本质上也是数据的输入与输出,所以也要以流为介质,每个文件都有一个与之对应的文件信息区(也就是所谓的流),我们可以通过定义FILE*(文件指针)类型的变量实现与文件有关的操作。

标准流

C语言程序在启动时默认打开了三个流:

  • stdin —— 标准输入流,用于获取从键盘上输入的数据,如scanf,fscanf(后续会讲)等
  • stdout —— 标准输出流,将从键盘获取的数据显示在控制台(就是屏幕)上,如printf,fprintf等
  • stderr —— 标准错误流,将错误信息显示在控制台上

            标准流可以理解为数据读取和输出都是在屏幕上进行的,而在文件操作时会用到文件流,也就是专门进行文件操作的流,通过文件流就可以使用各种函数较好的对文件进行维护。

    文件操作的步骤

            那么我们该如何找到文件呢?

    FILE* pf=NULL;

            C语言规定,所有的文件操作都是基于文件类型的指针,也就是说,通过⽂件指针变量能够间接找到与它关联的⽂件。

    文件操作大概可以分为三步:

    1. 打开文件(fopen)
    2. 读/写文件
    3. 关闭文件(fclose)

    代码框架如下:

            VS编译环境下需要在头文件前加#define  _CRT_SECURE_NO_WARNINGS预编译指令,因为编译器认为fopen是不安全的。

            几乎所有的文件操作的都是基于这个模板开展的。

    int main()
    {
    	//创建文件指针并打开文件
    	FILE* pf = fopen("test_3_26", "r");
    	//判断是否能打开文件
    	if (pf == NULL)
    	{
    		perror("fopen");//显示报错信息
    		return 1;
    	}
    	//文件操作(读/写)
        /*.......*/
    	//关闭文件
    	fclose(pf);
    	pf = NULL;//将pf置空防止其成为野指针
    	return 0;
    }

    接下来我们会对在文件操作中常用的函数进行讲解。

    文件的打开与关闭 

    fopen

    作用:打开指定路径下的文件。

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

    参数1

    const char * filename:打开文件的路径,可分为绝对路径和相对路径:

    • 绝对路径是文件或目录在文件系统中的完整路径,从根目录开始一直到目标文件或目录的路径描述。

      使用绝对路径时,需要提供完整的路径信息,包括根目录。

      例如,Windows 系统中的绝对路径可能类似于 C:\Users\Username\Documents\photos,Linux 或 macOS 中的绝对路径可能类似于 /home/username/documents/photos

    • 相对路径是相对于当前工作目录(当前所在位置)的路径。

      使用相对路径时,文件或目录的位置是相对于当前位置的描述,不需要从根目录开始描述。

      例如,在一个名为 documents 的文件夹中有一个子文件夹 photos,要访问 photos 文件夹可以使用相对路径 ./photos。在C程序中如果文件和main文件在同一个文件夹下,相对路径就是文件名+后缀名。

      参数2

      const char * mode:打开文件的方式(只需要记最常用的几种即可)

      ⽂件使⽤⽅式含义如果指定⽂件不存在
      “r”(只读)为了输⼊数据,打开⼀个已经存在的⽂本⽂件出错
      “w”(只写)为了输出数据,打开⼀个⽂本⽂件建⽴⼀个新的⽂件
      “a”(追加)向⽂本⽂件尾添加数据建⽴⼀个新的⽂件
      “rb”(只读)为了输⼊数据,打开⼀个⼆进制⽂件出错
      “wb”(只写)为了输出数据,打开⼀个⼆进制⽂件建⽴⼀个新的⽂件
      “ab”(追加)向⼀个⼆进制⽂件尾添加数据建⽴⼀个新的⽂件
      “r+”(读写)为了读和写,打开⼀个⽂本⽂件出错
      “w+”(读写)为了读和写,建议⼀个新的⽂件建⽴⼀个新的⽂件
      “a+”(读写)打开⼀个⽂件,在⽂件尾进⾏读写建⽴⼀个新的⽂件
      “rb+”(读写)为了读和写打开⼀个⼆进制⽂件出错
      “wb+”(读 写)为了读和写,新建⼀个新的⼆进制⽂件

      建⽴⼀个新的⽂件

      返回值:如果打开文件成功返回该文件的地址,打开失败返回NULL。

      样例:

      /*文件操作模板省略*/
      FILE* pf = fopen("test_3_26", "r");//以“只读”的方式打开文件
      if (pf == NULL)
      {
          fclose(pf);//关闭文件
      	perror("fopen");
      	return 1;
      }

      fclose  

      作用:关闭参数指针指向的文件

      int fclose ( FILE * stream );

      参数FILE*stream:直接传入指向要关闭文件的指针即可(如上文中的pf)。

      返回值:如果文件被成功关闭则返回返回0,如果失败返回非0值 。

       文件的顺序读写

      函数名功能适⽤于
      fgetc字符输⼊函数所有输⼊流
      fputc字符输出函数所有输出流
      fgets⽂本⾏输⼊函数所有输⼊流
      fputs⽂本⾏输出函数所有输出流
      fscanf格式化输⼊函数所有输⼊流
      fprintf格式化输出函数所有输出流
      fread⼆进制输⼊⽂件
      fwrite⼆进制输出⽂件

              对于本文来说,适用于所有流的意思是该函数既可以在标准流中进行输入或输出,也可以在文件中输入或输出,只适用于文件流代表该函数只能在文件中进行数据操作。

      fgetc

      作用:从文件流中获取一个字符(一次只能获取一个字符),需要注意的是每次调用fgetc函数后文件中的光标会后移读取下一个字符,直到EOF。

      int fgetc ( FILE * stream );

      参数:指向指定文件的指针。

      返回值:如果成功读取到字符,则返回该字符的ASCII码值;如果读取失败或文件结束(EOF)返回EOF。

      样例:

      //读取文本文件text_3_26中的所有字符
      /*文件操作模板省略*/
      int ch = 0;
      while ((ch = fgetc(pf)) != EOF)
      {
      	printf("%c\n", ch);
      }

      输出结果:

      C语言,文件操作详解,C语言文件操作详解指南 第1张

      fputc

      作用:每次向文件中写入一个字符,写入成功后光标后移。

      int fputc ( int character, FILE * stream );

      参数:

      1. int character:要写入文件的字符
      2. FILE * stream:指向要写入文件的指针

      返回值:如果字符被成功写入返回被写入字符的ASCII值,如果写入失败返回EOF。

      样例:

      /*文件操作模板省略*/
      fputc('a', pf);
      fputc('b', pf);
      fputc('c', pf);
      fputc('d', pf);
      fputc('e', pf);

      输出结果:

      C语言,文件操作详解,C语言文件操作详解指南 第2张

      fputs

      作用:向文件中写入字符串

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

      参数:

      1. const char * str:被写入的字符串。
      2. FILE * stream:指向文件的指针。

      返回值:成功写入返回一个非负值,写入失败返回EOF。

      样例:

              在多次调用fputs函数时如果不加'\n'修饰,字符串会在上次光标停留处继续打印在同一行,在字符串后加上'\n'才会换行输出。

      • 不加'\n'
        fputs("hello world", pf);
        fputs("hello world", pf);

        运行结果:

        C语言,文件操作详解,C语言文件操作详解指南 第3张

        • 加'\n'
          fputs("hello world\n", pf);
          fputs("hello world", pf);

          运行结果:

          C语言,文件操作详解,C语言文件操作详解指南 第4张

          fgets

          作用:从文件中最多读取num-1个字符并存入字符串,并在字符串结尾加上'\0'(第num个字符)

          char * fgets ( char * str, int num, FILE * stream );

          参数:

          1. char * str:指向从文件中读取的字符串的字符指针。
          2. int num:最多从文件中读取的num-1个字符,第num位放'str'。

          返回值:成功后,该函数返回 文件末尾。如果在尝试读取字符时遇到并且 str,返回NULL。如果在读取任何字符之前发生这种情况,则返回的指针为空指针NULL(str 的内容保持不变)。如果发生读取错误,则报错,并返回空指针NULL(但 

          char arr[10] = { 0 };
          fgets(arr, 10, pf);
           指向的内容可能已更改)。

          样例:

          /*文件操作模板省略*/
          char arr[20] = { 0 };
          while (fgets(arr, 20, pf) != NULL)//读取到文件末尾返回NULL
          {
          	printf("%s", arr);
          }

               C语言,文件操作详解,C语言文件操作详解指南 第5张

             C语言,文件操作详解,C语言文件操作详解指南 第6张

                  fgets只能读取在同一行的字符,而且如果条件允许'\n'也会读取进来,但是不会换行的读取。

          读取文件中的全部数据:

           fscanf

          运行结果:

                  C语言,文件操作详解,C语言文件操作详解指南 第7张

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

          作用:从文件中读取格式化的数据。

        • FILE * stream:打开文件的指针。
        • 参数:

          1. 参数数量不固定,根据变量类型和数量而定
          2. 文件末尾

          返回值:成功后,该函数返回成功填充的参数列表的项数。也可能由于匹配失败、读取错误或文件末尾的范围而更少(甚至为零)。如果在读取时发生读取错误或到达

          struct Student
          {
          	int age;
          	char name[20];
          	float score;
          };
          /*文件操作模板省略*/
          struct Student s = { 0 };
          fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score));//从文件中获取数据
          printf("%s %d %.1f", s.name, s.age, s.score);
          ,报错。而且,如果在成功读取任何数据之前发生任何情况,则返回 EOF。

          样例:

          fprintf

          运行结果:

          C语言,文件操作详解,C语言文件操作详解指南 第8张

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

          作用:向文件中写入格式化数据(以文本的形式)

        • FILE * stream:指定的文件指针
        • 参数:

          1. const char * format, ...对应向文件中输出的数据的类型
          2. struct Student
            {
            	char name[20];
            	int age;
            	float score;
            };
            /*文件操作模板省略*/
            //FILE* pf = fopen("test_3_26.txt", "w+");//打开方式修改为"w+"
            struct Student s = {"张三",18,65.5};
            fprintf(pf, "%s %d %f", s.name, s.age, s.score);

          返回值:成功后,将返回写入的字符总数。如果发生写入错误,则返回负数。

          样例:

          fwrite

          运行结果:

          C语言,文件操作详解,C语言文件操作详解指南 第9张

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

          作用:以二进制的的形式向文件中写入

        • const void * ptr:指向被写入元素内存块的指针。
        • 参数:

          1. size_t size:被写入元素的数据类型。
          2. size_t count:写入元素的个数。
          3. FILE * stream:文件指针。
          4. count

          返回值:返回成功写入的元素总数。如果此数字与 size 参数不同,则写入错误会阻止函数完成。如果 count 或 

          /*文件操作模板省略*/
          //FILE* pf = fopen("test_3_26.txt", "rb");//以"rb"打开文件
          int arr1[5] = { 1,2,3,4,5 };
          int arr2[5] = { 0 };
          fwrite(arr1, sizeof(arr1[0]), 5, pf);//以二进制形式写入
           为零,则函数返回零。

          样例:

          fread

          运行结果:

                  以二进制形式输入的数据我们是看不懂的,需要搭配fread函数(见后文)读出来。

          C语言,文件操作详解,C语言文件操作详解指南 第10张

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

          作用:以二进制的形式从文件中读取数据(只适用于文件流)。

        • void * ptr:从文件中读取的数据放在ptr中。
        • 参数:

          1. size_t size:读取数据类型的大小。
          2. size_t count:读取元素的个数。
          3. FILE * stream:文件指针。
          4. count

          返回值:返回成功读取的元素总数。如果此数字与 文件末尾 参数不同,则表示读取时发生读取错误或到达size。如果 count 或 

          文件的随机读写

           为零,则该函数返回零。

          样例:

          /*文件操作模板省略*/
          //FILE* pf = fopen("test_3_26.txt", "rb");//以"rb"打开文件
          int arr1[5] = { 1,2,3,4,5 };
          int arr2[5] = { 0 };
          fread(arr2, sizeof(arr2[0]), 5, pf);//以二进制形式读取
          for (int i = 0; i  
           

          运行结果:

          C语言,文件操作详解,C语言文件操作详解指南 第11张

          fseek

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

          作用: 根据⽂件指针的位置和偏移量来定位⽂件指针。

        • FILE * stream:文件指针。
        • 参数:

          1. long int offset:相对于起始位置的偏移量。
          2. int origin:起始位置。
          3. 第三个参数起始位置一共有三种类型
            参数
          • /*文件操作模板省略*/
            //FILE* pf = fopen("test_3_26.txt", "r");//以"r"打开文件
            int ch1 = fgetc(pf);//a
            int ch2 = fgetc(pf);//b
            int ch3 = fgetc(pf);//c
            printf("%c %c %c\n", ch1, ch2, ch3);
            fseek(pf, 0, SEEK_SET);//相对于文件开头偏移0个单位
            int ch4 = fgetc(pf);//a
            printf("%c\n", ch4);
            
            文件指针的起始位置SEEK_SET
            文件开头SEEK_CUR
            文件指针的当前位置SEEK_END

            文件末尾

            返回值:如果成功,该函数将返回零。否则返回非零值。

            样例:

                    当参数origin位SEEK_END时,此时的偏移量应为负值。

            • 偏移量位正或0
              /*文件操作模板省略*/
              int ch1 = fgetc(pf);//a
              int ch2 = fgetc(pf);//b
              int ch3 = fgetc(pf);//c
              printf("%c %c %c\n", ch1, ch2, ch3);
              fseek(pf, -1, SEEK_END);//相对于文件末尾偏移1个单位
              int ch4 = fgetc(pf);//g
              printf("%c\n", ch4);

              运行结果:

              C语言,文件操作详解,C语言文件操作详解指南 第12张

              C语言,文件操作详解,C语言文件操作详解指南 第13张

              • 偏移量为负

                ftell

                运行结果:

                C语言,文件操作详解,C语言文件操作详解指南 第14张

                long int ftell ( FILE * stream );

                作用: 返回⽂件指针相对于文件开头的偏移量。(fseek函数可以规定字符指针的位置,见前文)

                /*文件操作模板省略*/
                fseek(pf, 0, SEEK_END);//文件末尾
                printf("%d\n", ftell(pf));

                参数:FILE * stream:文件指针。

                返回值:文件指针相对于文件开头的偏移量。

                样例:

                        当文件指针位于文件末尾时,ftell的返回值就是该文件中所有的字符数。

                rewind

                运行结果:

                C语言,文件操作详解,C语言文件操作详解指南 第15张C语言,文件操作详解,C语言文件操作详解指南 第16张

                void rewind ( FILE * stream );

                作用:将文件指针的位置设置为开头。

                /*文件操作模板省略*/
                int ch1 = fgetc(pf);//a
                int ch2 = fgetc(pf);//b
                int ch3 = fgetc(pf);//c
                printf("%c %c %c\n", ch1, ch2, ch3);
                rewind(pf);
                int ch4 = fgetc(pf);//a
                printf("%c\n", ch4);

                参数:FILE * stream:文件指针。

                样例:

                文件读取结束的判定

                运行结果:

                C语言,文件操作详解,C语言文件操作详解指南 第17张

                C语言,文件操作详解,C语言文件操作详解指南 第18张

                feof 的作⽤是:当⽂件读取结束的时候,判断是读取结束的原因是否是:遇到⽂件尾结束。 1. ⽂本⽂件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets ) 例如: • fgetc 判断是否为 EOF . • fgets 判断返回值是否为 NULL . 2. ⼆进制⽂件的读取结束判断,判断返回值是否⼩于实际要读的个数。 例如: • fread判断返回值是否⼩于实际要读的个数。

0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码