C语言:文件操作2(又一万字?)

关于文件操作这章内容,因为知道内容较多所以我分两篇发了,但是还是没料到第二篇还是这么多,达到了一万多字!!!作者本人真的将知识点进行了超级详解分析并且举了很多例子来帮助读者理解,本文章较长,请耐心阅读体会,如果读完对你有用的话,请给作者留下你的:


5.文件的顺序读写

顺序读写函数介绍

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

1.fputc函数

运行完之后中,打开data.txt文件,里面放的就是xyz。

我们也可以用循环来写文件。


这就是fputc函数,一次只能写入一个字符 ,但是我们可以调用它写入多个字符,在开始写文件时,有一个光标在起始位置,随着fputc一次一次的写入,光标会按照顺序往下走,这样的话你就是按照顺序写进去的。

如果该函数指定为标准输出流,就是回打印到屏幕上

所以fputc适用于所有输出流:如:文件,stdout。

2.fgetc函数




从上面打印结果可得它是顺序读的方式。

我们也可以写一个循环来读文件

它适用于所有输入流如:文件,stdin这是从键盘输入的,当我们按下crtrol z它会返回一个EOF循环停止。

上面是一个字符的读写,我们来看一行字符的读写。

写文件

3.fputs函数




想要换到两行上,可以加上\n。


读文件

4.fgets函数



我们只读到前4个字符,所以当我们写n个字符的时候,只会读n-1的字符,最后一位留给\0。


打印的时候不用加换行符,因为写文件的时候字符串里面有\n,所以打印的时候会自动换行。

再次读文件得时候,读的是第二行的信息

同样也把末尾的\n也读走了,来看打印结果

我们同样也可以用循环来读文件,fgets函数若读取失败的话,会返回空指针,根据该特性,我们可以这样写代码

我们来直接多加几行。

我们再来看fscanf函数和fprintf函数。

5.fprintf函数


运行完之后,看是否这些带有格式的数据被放在文件中。

记住我们将带有格式的数据,以格式写入文件中。

6.fscanf函数


结果

当我们这样写代码的时候一个可以代替printf函数 ,一个可以代替scanf函数。

我们再来看两个函数sprintf和sscanf。

7.sprintf函数


8.sscanf函数


我们来将上面内容稍微总结一下

fread和fwrite函数

9.fwrite函数


我们来运行一下,看看到底能不能写到文件中去。

我们打开data.txt文件,看不懂里面的内容因为它是二进制的。

我们可以这样操作:添加现有项,把data.txt文件添加进来,再以二进制形式打开它(在打开方式里面找),我们以二进制形式来看文件的内容。

fread是可以读取二进制的信息的。

10.fread函数

我们来运行看打印结果

我们同样也可以写个循环来读文件

但是当我们不知道文件中有几个元素该怎么读呢?我们来看fread函数的返回值

fread函数它的返回值是成功读取的个数,若没有成功读取就返回0,所以我们可以这样写代码


fread函数的返回值如果小于要求读取的个数,就意味着这是最后一次读取了。


6.文件的随机读写

1.fseek

根据文件指针的位置和偏移量来定位文件指针(文件内容的光标)。

c 复制代码
1   int fseek ( FILE* stream, long int offset, int orgin );


假设我们有一个文件data.txt里面是abcdef,我们用fread函数,写第二个参数时,要根据第三个参数来写,先确定光标位置,再给出偏移量。

这个时候我们就跳过了b和c字符,读取到了d。

另外两个写法,就是看你的起始地址从哪里开始记,改变偏移量实现读取。


最后一个方法因为光标是从后往前偏移,所以偏移量为-3。

2.ftell

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

c 复制代码
1   long int ftell ( FILE * stream );

根据我上面所举的例子,当我们上面读完d之后,光标指向了e,我们可以用ftell函数来计算当前光标相对起始地址的偏移量。


3.rewind

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

c 复制代码
1   void rewind ( FILE * stream );



7.文件读取结束的判定

1.被错误使用的 feof

牢记:在文件读取过程中,不能用feof函数的返回值直接来判断文件的是否结束。feof 的作用是:当文件读取结束的时候,判断读取结束的原因是否是:遇到文件尾结束。

1.文本文件读取是否结束,判断返回值是否为EOF (fgetc),或者NULL (fgets)例如:

fgetc 判断是否为EOF.

fgets 判断返回值是否为NULL

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

例如:

fread判断返回值是否小于实际要读的个数。

2.文本文件的例子

c 复制代码
#include <stdio.h>
#include <stdlib.h>

int main (void)
{
     int c; //注意:int,非char,要求处理EOF
     FILE* fp = fopen("data.txt","r");
     if(!fp)
     {
           perror("File opening failed");
           return EXIT_FAILIRE;
      };
      //fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOF
      while((c = fgetc(fp) != EOF )// 标准C I/O读取文件循环
      {  
          putchar(c);
      }
      //判断是什么原因结束的
      if(ferror(fp))
           puts("I/O error when reading");
      else if (feof(fp))
           puts("EOF of file reached successfully");
      fclose(fp);
}
     

ferror(fp)如果返回是非零值,说明在读取过程中发生错误,并没有读到文件末尾。

feof(fp)返回值为非零值,说明读到文件末尾停止了。

3.二进制文件的例子

c 复制代码
#include <stdio.h>

enum { SIZE = 5 };

int main(void)
{
          double a[SIZE] = {1,2,3,4,5};
          FILE* fp = fopen("data.bin","wb");//必须用二进制模式
          fwrite(a,sizeof *a,SIZE,fp); //写 double 的数组
          fclose(fp);
          double b[SIZE];
          fp = fopen("data.bin","rb");
          size_t ret_code = fread(b,sizeof *b, SIZE,fp); //读 double 的数组
          if(ret_code == SIZE)
          {
               puts("Array read successfully, contents: ");
               for(int n = 0; n<SIZE; ++n)
                  printf("%f ", b[n]);
               putchar('\n');
            }
            else
            {
             //error handing
             if (feof(fp))
                 printf("Error reading test.bin: unexpected end of file\n");
             else if(ferror(fp))
             {
                perror("Error reading test.bin");
             }
       }
     fclose(fp);
     return 0;
}

8.文件缓冲区

ANSIC标准采用"缓冲文件系统"处理数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正

在使用的文件开辟一块"文件缓冲区"。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到

磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓

冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。


完结!!!

相关推荐
uhakadotcom30 分钟前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom34 分钟前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom1 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom1 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试
咖啡教室2 小时前
前端开发日常工作每日记录笔记(2019至2024合集)
前端·javascript
咖啡教室2 小时前
java日常开发笔记和开发问题记录
java
咖啡教室2 小时前
java练习项目记录笔记
java
咖啡教室2 小时前
前端开发中JavaScript、HTML、CSS常见避坑问题
前端·javascript·css
鱼樱前端3 小时前
maven的基础安装和使用--mac/window版本
java·后端
RainbowSea3 小时前
6. RabbitMQ 死信队列的详细操作编写
java·消息队列·rabbitmq