【C语言】探索文件读写函数的全貌(三)

简介: 【C语言】探索文件读写函数的全貌

【C语言】探索文件读写函数的全貌(二)https://developer.aliyun.com/article/1617244

七、文件的随机读写

由于文本文件和二进制文件使用方面存在差异,下面三个函数将采用二进制文件

7.1 fseek()

函数部分说明】:

功能上:

  • 重新定位流位置指示器,根据文件指针的位置和偏移量定位文件指针

返回值:

  • 成功,返回零,失败,返回非零值

注意】:

  • 二进制文件:要从原点偏移的字节数
  • 文本文件:零或 ftell 返回的值

【原点】

特别注意的是起源(从哪个位置),用作偏移参考位置

  • SEEK_SET :文件开头
  • SEEK_CUR :文件指针的当前位置
  • SEEK_END: 文件末尾
int main()
{
  FILE* pf = fopen("test1.txt", "wb");//打开一个二级制文件
  if (pf == NULL)
  {
    perror("fopen fail!!!");
    return;
  }
  fputs("This is an apple", pf);
  fseek(pf, 3, SEEK_SET);
  fputs("sam", pf);
    
  fseek(pf, -3, SEEK_END);//文件指针往前走
  fputs("xxx", pf);
    fclose
  return 0;
}

7.2 ftell()

函数部分说明】:

功能上:

  • 返回流的位置指示器的当前值(返回文件指针相对于起始位置的偏移量 )

返回值:

  • 对于二进制流,这是从文件开头开始的字节
  • 对于文本流,数值可能没有意义
int main()
{
    FILE* pf = fopen("test1.txt", "wb");//打开一个二级制文件
    if (pf == NULL)
    {
        perror("fopen fail!!!");
        return;
    }
    fputs("This is an apple", pf);
    fseek(pf, 0, SEEK_END);
    int size = ftell(pf);
    printf("%d", size);//size==16,源头到参考位置的字节数
    fclose(pf);
    pf = NULL;
    return 0;
}

7.3 rewind()

函数部分说明】:

  • 功能:让文件指针的位置回到文件的起始位置
int main()
{
    FILE* pf = fopen("test1.txt", "wb");//打开一个二级制文件
    if (pf == NULL)
    {
        perror("fopen fail!!!");
        return;
    }
    fputs("This is an apple", pf);
    fseek(pf, 0, SEEK_END);
    rewind(pf);
    int size = ftell(pf);
    printf("%d", size);
    fclose(pf);
    pf = NULL;
    return 0;
}


八、文件读取结束的判断

牢记】:在文件读取过程中,不能用feof函数的返回值直接判断文件是否结束

8.1 ferror()

函数部分说明】:

  • 功能:检查错误指示器
  • 返回值:检查是否设置了与关联的错误指示器,如果设置了,则返回一个不同于零的值

8.2 feof()

函数部分说明】:

  • 功能:检查文件结束指示器
  • 返回值:**如果设置了与流关联的文件结束指示符,则返回非零值。**否则,返回零。

小总结

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

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


检查文件读取结束场景

while ((c = fgetc(fp)) != EOF) // 标准C I/O读取
{
  putchar(c);
}
//判断是什么原因结束的
  if (ferror(fp))
puts("I/O error when reading");
  else if (feof(fp))
puts("End of file reached successfully");

九、文件缓冲区

ANSIC标准采⽤“缓冲文件系统”处理的数据⽂件的,所谓缓冲⽂件系统是指系统⾃动地在内存中为程序中每⼀个正在使⽤的⽂件开辟⼀块“⽂件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读⼊数据,则从磁盘⽂件中读取数据输⼊到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的⼤⼩根据C编译系统决定的.上述过程转换为下图展示。

验证】:

int main()
{
FILE*pf = fopen("test.txt", "w");
fputs("abcdef", pf);//先将代码放在输出缓冲区
printf("睡眠10秒-已经写数据了,打开test.txt⽂件,发现⽂件没有内容\n");
Sleep(10000);
printf("刷新缓冲区\n");
fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到⽂件(磁盘)
//注:fflush 在⾼版本的VS上不能使⽤了
printf("再睡眠10秒-此时,再次打开test.txt⽂件,⽂件有内容了\n");
Sleep(10000);
fclose(pf);
//注:fclose在关闭⽂件的时候,也会刷新缓冲区
pf = NULL;
return 0;
}

目的】:

程序延迟执行时间内,检查文本编辑器是否存在数据,等待程序睡眠时间过去,再次检查文本编辑器是否存在数据,验证内存和外存之间存在缓冲区

结论】:

因为有缓冲区的存在,C语⾔在操作文件的时候,需要做刷新缓冲区或者在⽂件操作结束的时候关闭文件。如果不做,可能导致读写⽂件的问题


相关文章
|
1天前
|
算法 搜索推荐 C语言
【C语言篇】深入理解指针4(模拟实现qsort函数)
【C语言篇】深入理解指针4(模拟实现qsort函数)
10 2
|
1天前
|
存储 C语言
【C语言】探索文件读写函数的全貌(二)
【C语言】探索文件读写函数的全貌
|
1天前
|
存储 编译器 C语言
【C语言】函数(涉及生命周期与作用域)
【C语言】函数(涉及生命周期与作用域)
|
27天前
|
存储 Serverless C语言
【C语言基础考研向】11 gets函数与puts函数及str系列字符串操作函数
本文介绍了C语言中的`gets`和`puts`函数,`gets`用于从标准输入读取字符串直至换行符,并自动添加字符串结束标志`\0`。`puts`则用于向标准输出打印字符串并自动换行。此外,文章还详细讲解了`str`系列字符串操作函数,包括统计字符串长度的`strlen`、复制字符串的`strcpy`、比较字符串的`strcmp`以及拼接字符串的`strcat`。通过示例代码展示了这些函数的具体应用及注意事项。
|
1天前
|
存储 编译器 C语言
【C语言篇】数组和函数的实践:扫雷游戏(附源码)
【C语言篇】数组和函数的实践:扫雷游戏(附源码)
7 0
|
1天前
|
C语言
【C语言】探索文件读写函数的全貌(一)
【C语言】探索文件读写函数的全貌
|
1天前
|
编译器 C语言 C++
【C语言】精妙运用内存函数:深入底层逻辑的探索
【C语言】精妙运用内存函数:深入底层逻辑的探索
|
1天前
|
存储 文件存储 C语言
【C语言】深入了解文件:简明指南
【C语言】深入了解文件:简明指南
|
1月前
|
存储 C语言
C语言程序设计核心详解 第十章:位运算和c语言文件操作详解_文件操作函数
本文详细介绍了C语言中的位运算和文件操作。位运算包括按位与、或、异或、取反、左移和右移等六种运算符及其复合赋值运算符,每种运算符的功能和应用场景都有具体说明。文件操作部分则涵盖了文件的概念、分类、文件类型指针、文件的打开与关闭、读写操作及当前读写位置的调整等内容,提供了丰富的示例帮助理解。通过对本文的学习,读者可以全面掌握C语言中的位运算和文件处理技术。
|
1月前
|
存储 C语言
C语言程序设计核心详解 第七章 函数和预编译命令
本章介绍C语言中的函数定义与使用,以及预编译命令。主要内容包括函数的定义格式、调用方式和示例分析。C程序结构分为`main()`单框架或多子函数框架。函数不能嵌套定义但可互相调用。变量具有类型、作用范围和存储类别三种属性,其中作用范围分为局部和全局。预编译命令包括文件包含和宏定义,宏定义分为无参和带参两种形式。此外,还介绍了变量的存储类别及其特点。通过实例详细解析了函数调用过程及宏定义的应用。