cpp整理学习笔记 文件I/O:随机存取fseek()和ftell()

    fseek()函数可以像对待一个数组一样对待一个文件,fopen()打开的文件中,fseek()可以直接移动到任意字节的位置。

   如果按反序显示一个文件,,且使用命令行参数获得要读取的文件的名字。(注:fseek()接受3个参数,返回一个int值),ftell()以一个long类型值返回一个文件的当前位置。

/*reverse.c   按反序显示一个文件*/
#include <stdio.h>
#include <stdlib.h>
#define CNTL_Z '\032'                         /*DOS文本文件中的文件结尾标记*/
#define SLEN 50
int main (void)
{
    char file[SLEN];
    char ch;
    FILE *fp;
    long count,last;
    
    puts("Enter tne name of the file to be processed:");
    gets(file);
    if ((fp=fopen(file,"rb"))==NULL){            /*只读和二进制模式,适用于二进制模式,但不一定适用于文本模式*/
        printf("resever can't open %s\n",file);
        exit(1);
    }
    fseek(fp,0L,SEEK_END);                        /*定位到文件结尾处*/
    last=ftell(fp);                               /*把从文件开始到文件结束的字节数目赋给last*/
    for(count=1L;count<=last;count++){
        fseek(fp,-count,SEEK_END);                /*回退,第一次循环将程序定位到文件结尾前的第一个字符,就是文件的最后一个字符,依次往前,一直到文件的第一个字符*/
        ch=getc(fp);                            
    /*针对DOS,UNIX下也可以工作*/
        if(ch!=CNTL_Z && ch != '\r')              /*防止程序打印“Ctrl+Z”字符*/
            putchar(ch);
    /*针对Macintosh*/
    /*if(ch == '\r')
        putchar('\n');
    else
        putchar(ch);        */
    }
    putchar('\n');
    fclose(fp);
    return 0;        
}

fseek()的工作方式

int fseek ( FILE * stream, long int offset, int origin );
在fseek()的三个参数中,第一个参数是一个已经被fopen()打开的文件(即搜索文件)的FILE指针;第二个参数是偏移量(即从起始点开始要移动的距离),这个参数必须是long类型的值,前移为正,后移为负,不懂为0;第三个参数是模式,标识起点。在ANSI下,stdio.h头文件指定了下列模式常量:

模式偏移量的起始点
SEEK_SET文件开始
SEEK_CUR当前位置
SEEK_END文件结尾
以前的定义分别用0L、1L、2L表示这些模式,L是long类型值。也可以其他头文件中定义模式常量。

比如,fp作为一个文件指针,

fseek(fp,0L,SEEK_SET);       //找到文件的开始处
fseek(fp,10L,SEEK_SET);      //找到文件的第10个字节
fseek(fp,2L,SEEK_CUR);       //从文件的当前位置向前移动2个字节
fseek(fp,0L,SEEK_END);       //到达文件的结尾处
fseek(fp,-10L,SEEK_END);     //从文件结尾处退回10个字节

如果正常,fseek()返回0;如果有错误,比如试图移动超过文件范围,fseek()返回-1.



ftell()函数为long类型,返回文件的当前位置。在ANSI下,ftell()函数在stdio.h头文件的中被声明.ftell()函数通过返回距离文件开始处的字节数来确定文件的位置,比如文件的第一个字节到文件的开始处的距离就是0,适用于二进制模式,但不一定适用于文本模式


 

1.二进制模式和文本模式

UNIX只有一种文件格式,上述程序可以无需改动(UNIX文件中通常不包含Ctrl+Z和\r)。而MS-DOS值得关注,许多MS-DOS编辑器使用Ctrl+Z标识文本文件的结尾,如果以文本文件的形式打开,并无大碍;如果以二进制模式打开,Ctrl+Z会被看做字符。而真正的文件在后面,除非紧跟着Ctrl+Z,否则是用空字符填满到256(或其他数)的倍数。DOS下不打印空字符。

2.MS-DOS用\r\n组合表示文本文件的换行符,以文本模式打开文件的C程序将\r\n看做\n。二进制模式中要向上述程序中处理\r。


由于ftell()在文本模式和二进制模式下的工作方式有所不同,ANSI C规定,对于文本模式,ftell()返回一个可以用作fseek()的第二个参数的值。例如,MS-DOS中,ftell()返回一个将\r\n看做一个字符的计数值。

在文本模式中,确保有效的fseek()调用只有以下这些

fseek(file,0L,SEEK_SET)到文件开始
fseek(file,0L,SEEK_CUR)在当前位置不动
fseek(file,0L,SEEK_END)到文件结尾
fseek(file,ftell-pos,SEEK_SET)到距文件开始处ftell-pos字节的位置,ftel-pos是ftell的返回值


有一点,fseek()和ftell()两个函数是相对于long类型而言,对于更大的数值,ANIS C引入了两个用来处理较大文件的新的定位函数,类型为fpos_t(file position type,文件定位类型)

1.fgetpos()函数原型:int fgetpos(FILE *restrict stream,fpos_t *restrict pos),调用成功返回0,否则非零

2.fsetpos()函数原型:int fsetpos(FILE *stream,const fpos_t *pos),调用成功返回0,否则非零,此处fpos_t的值是通过调用fgetpos()获取的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值