zoukankan      html  css  js  c++  java
  • C语言中文件定位函数总结

    C语言中文件定位函数主要是:fseek, ftell, fsetpos, fgetpos。

    先来讲前两个函数,这是最基本的定位函数:


      fseek函数:能把文件指针移动到文件任何位置,其原型是:int fseek(FILE *fp, long offset, int fromwhere);

      参数解释:第一个参数为要进行定位的文件的指针;第二个参数为定位的偏移量,一个有符号的long类型值,正数表示文件指针向后偏移,负数表示文件指针向前偏移,0 表示不进行偏移;第三个参数表示文件指针从哪个位置开始偏移,有三个值可选,SEEK_SET & SEEK_CUR & SEEK_END,分别表示文件第一个字节(即第零个位置),文件指针当前所指字节(即当前位置)和文件EOF位置。

      返回值:返回 0 表示操作成功,返回非 0 表示操作失败。

      其他注意:该函数不能定位到第一个字节之前的位置,如果尝试这样操作会导致fseek返回 -1,即操作失败,比如这样的代码“j = fseek(fp, -4L, SEEK_SET );”,其中 j 值就是 -1;但是,该函数能定位到EOF位置之后的位置,并且不报错,即使这样是没有意义的,比如这样的代码“j = fseek(fp, 4L, SEEK_END)”,返回值 j 是 0,并且此时 ftell(fp) 返回值是SEEK_END + 4。


      ftell函数:能返回当前文件指针所在的位置(文件的第一个字节所在位置是零),其原型是:long ftell(FILE *fp);

      参数解释:有且仅有一个参数,为一个文件的指针。

      返回值:有符号long类型的正向值,即0~2147483647。

      其他注意:暂无。


    实际上,前两个函数对文件指针的定位虽然都很方便,但是它们都有一个局限性,那就是它们能定位的最大字节是依据 long 类型的取值范围决定。比如 fseek(fp, max_pos, SEEK_SET);,它能移动的最大偏移量是 max_pos = 2147483647字节,即1GB,对于大于1GB的文件来说就力不从心了。

    所以ANSI C推出了解决大文件定位的方案,即后两个函数!(不过,即使是现在,直接处理一个超过1G的单文件还是比较少的)

    在说这两个函数之前,先要介绍一个数据类型fpos_t,它是一个结构体类型,保存着文件指针的位置,并且这种数据类型只能被fgetpos和fsetpos函数使用。


      fsetpos函数:将文件指针的位置设置为fpos_t类型变量所保存的位置,其原型是:int fsetpos(FILE *, const fpos_t *)

      参数解释:第一个参数为一个文件的指针;第二个参数为一个fpos_t类型的指针。

      返回值:0 表示操作成功,非 0 表示操作失败。

      其他注意:暂无。


      fgetpos函数:将文件指针的位置保存到fpos_t类型变量中,其原型是:int fgetpos(FILE *, fpos_t *)

      参数解释:同fsetpos。

      返回值:同fsetpos。

      其他注意:暂无。


    总结:后两个函数通常是fseek函数偏移累加之后超过long范围时才用到,例如如下代码:

    fpos_t pos;
    //定义一个fpos_t类型的变量pos
    f = fopen("a.txt", "r");
    //假设a.txt是一个超过1G的文件
    fseek(f, 2000000000L, SEEK_SET);
    //向后偏移20亿字节
    fseek(f, 1000000000L, SEEK_CUR);
    //再向后面偏移10亿字节
    //此时,文件指针的位置已经超过了signed long的正向范围,就需要用fpos_t类型变量来保存文件指针位置了
    fgetpos(f, &pos);
    //此时,当前文件指针的位置已保存到pos变量中了
    fseek(f, 5000L, SEEK_CUR);
    printf("%x
    ", getc(f));
    //再向后偏移5千字节,并取出偏移后所在的字节,以十六进制打印出来
    fsetpos(f, &pos);
    //利用fsetpos函数重置文件指针,根据最后一次fgetpos保存的pos值,这次函数操作将向前偏移5千字节
    printf("%x
    ", getc(f));
    //以十六进制打印出当前字节
    fclose(f);
    //释放文件流

     上述代码可能有点抽象,因为你可能一时间找不到大于1G的文件,那么我们就用小文件来演示一下:

    假设文件"utf8.txt"的十六进制结构如下:

    41 42 43 56 57 44 44 4B

    C语言代码如下:

    FILE * f1;
    fpos_t pos;
    f1 = fopen("utf8.txt", "r");
    fseek(f1,2,SEEK_SET);
    fgetpos(f1, &pos);
    fseek(f1,4,SEEK_SET);
    printf("%x
    ", getc(f1));
    fsetpos(f1,&pos);
    printf("%x
    ", getc(f1));
    fclose(f1);

    输出结果:

    57
    43
    Press any key to continue

  • 相关阅读:
    20175215 2018-2019-2 第十周java课程学习总结
    2018-2019-2 20175215 实验三《敏捷开发与XP实践》实验报告
    MyCP(课下作业,必做)
    2018-2019-1 20175234 《信息安全系统设计基础》有关系统调用的部分学习
    2018-2019-1 20175234 《信息安全系统设计基础》第2周学习总结
    一个想要拥有正常的F1~F12的联想小新潮
    2018-2019-1 20175234 《信息安全系统设计基础》第1周学习总结
    Visual C++ 6.0精简绿色版下载及简单使用教程
    20175234 2018-2019-2 实验五 网络编程与安全
    20175234 2018-2019-2 实验四 Android程序设计
  • 原文地址:https://www.cnblogs.com/ryzz/p/9357158.html
Copyright © 2011-2022 走看看