转自
有三种方法可以定位流。
1.ftell函数和fseek函数
这两个函数自V7以来就存在了。但是它们假定文件的位置可以存放在一个长整型中。
函数声明如下:
#includelong ftell(FILE* fp); //如果成功返回当前文件位置指示,出错则返回-1. int fseek(FILE* fp, long offset, int whence); //如果成功则返回0,出错则返回非0值。 void rewind(FILE* fp); //定位到流的开头
fseek函数中的whence的值与lseek函数相同:SEEK_SET表示从文件的起始位置开始,SEEK_CUR表示从当前文件位置开始,SEEK_END表示从文件的尾端开始。
实践:
#includeint main(void){ FILE* fp; int result; int c; if((fp = fopen("a.txt", "r+")) == NULL){ result = -1; perror("fopen"); goto FINALLY; } printf("position:%ld\n",ftell(fp)); if((c = fgetc(fp)) != -1){ printf("read c:%c\n",c); } if((c = fgetc(fp)) != -1){ printf("read c:%c\n",c); } printf("position:%ld\n",ftell(fp)); if(fseek(fp, 3, SEEK_CUR) != 0){ result = -1; perror("fseek"); goto FINALLY; } printf("position:%ld\n",ftell(fp)); rewind(fp); printf("position:%ld\n",ftell(fp)); FINALLY: if(fp != NULL){ fclose(fp); } return result; }
运行结果:
$ cat a.txt abcdefghijklmnopqrstuvwxyz $ ./a.out position:0 read c:a read c:b position:2 position:5 position:0
2.ftello和fseeko函数
Single UNIX Specification引入了这2个函数,可以使文件偏移量不必一定使用长整型,它们使用off_t数据类型代替了长整型。
#includeoff_t ftello(FILE* fp); //成功则返回当前文件的位置指示,出错则返回-1 int fseeko(FILE* fp, off_t offset, int whence); //成功则返回0,出错返回非0值
实践:
$ cat a.txt abcdefghijklmnopqrstuvwxyz $ ./a.out position:0 read c:a read c:b position:2 position:5
3.fgetpos和fsetpos函数
这2个函数是ISO C引进的,它们使用一个抽象数据类型fpos_t记录文件的位置,这种数据类型可以定义为记录一个文件位置所需的长度。
这2个函数如果成功返回0,出错则返回非0值。fgetpos将文件位置当前的值存入到pos中,以后调用fsetpos时,可以使用此值将流重新定位到该位置。
实践:
#includeint main(void){ FILE* fp; int result; int c; fpos_t pos1,pos2; if((fp = fopen("a.txt", "r+")) == NULL){ result = -1; perror("fopen"); goto FINALLY; } if((c = fgetc(fp)) != -1){ printf("read c:%c\n",c); } if((c = fgetc(fp)) != -1){ printf("read c:%c\n",c); } if(fgetpos(fp,&pos1) != 0){ result = -1; perror("fgetpos"); goto FINALLY; } printf("position:%ld\n",pos1); if((c = fgetc(fp)) != -1){ printf("read c:%c\n",c); } if((c = fgetc(fp)) != -1){ printf("read c:%c\n",c); } if(fgetpos(fp,&pos2) != 0){ result = -1; perror("fgetpos"); goto FINALLY; } printf("position:%ld\n",pos2); if(fsetpos(fp, &pos1) != 0){ result = -1; perror("fsetpos"); goto FINALLY; } if(fgetpos(fp,&pos2) != 0){ result = -1; perror("fgetpos"); goto FINALLY; } printf("position:%ld\n",pos2); FINALLY: if(fp != NULL){ fclose(fp); } return result; }
运行结果: $ cat a.txt abcdefghijklmnopqrstuvwxyz $ ./a.out read c:a read c:b position:2 read c:c read c:d position:4 position:2