这个lseek,fseek,read,fread之间的区别是什么?

Sup*_*ing 4 c

我在调用这些函数:

unsigned blah[5];
lseek(0, 100, SEEK_CUR);
read(0, blah, sizeof(blah));
Run Code Online (Sandbox Code Playgroud)

FILE *fr;
fr = fopen(arg[1], "r");
unsigned blah[5];
fseek(fr, 100, SEEK_CUR);
fread(blah, 1, sizeof(blah), fr);
Run Code Online (Sandbox Code Playgroud)

我运行第一个代码运行此命令:

cat TEXTFILE | ./a.out
Run Code Online (Sandbox Code Playgroud)

我运行第二个代码运行此命令:

./a.out TEXTFILE
Run Code Online (Sandbox Code Playgroud)

但是,我得到了不同的结果.虽然第一个搜索正确,所以它读取正确的文本,第二个不是.我想使用第二种格式,那么我做错了什么?

Tim*_*nes 5

通过添加对open(filename,O_RDONLY);第一个示例的调用,两者都适合我.我怀疑你的问题是因为lseek(0, 100, SEEK_CUR);要求对标准输入进行搜索.你不能总是寻求标准 - 如果你有:

 cat file | ./my_program 
Run Code Online (Sandbox Code Playgroud)

然后标准输入是一个fifo,你不能寻求.如果我在我的系统上执行此操作,请通过返回-1错误"非法搜索"来查找失败.这可能是您遇到的问题,您可能没有注意到,因为您没有在示例中检查搜索调用的返回值.

请注意,如果您有:

 ./my_program < file
Run Code Online (Sandbox Code Playgroud)

然后标准输入是一个文件,你可以寻求.在我的系统上,查找返回100,输出正确.


这是一个程序,您可以用来说明返回值:

int main(void){ 

  int fd = 0;
  char blah[5];
  printf("Seek moved to this position: %d\n",lseek(fd, 100, SEEK_CUR));
  perror("Seek said");
  printf("Then read read %d bytes\n",read(fd, blah, sizeof(blah)));
  printf("The bytes read were '%c%c%c%c%c'\n",blah[0],blah[1],blah[2],blah[3],blah[4]); 
}                       
Run Code Online (Sandbox Code Playgroud)

这是两个执行:

 $ ./a.out < text
 Seek moved to this position: 100
 Seek said: Success
 Then read read 5 bytes
 The bytes read were '+++.-'
Run Code Online (Sandbox Code Playgroud)

(那些是该文件中位置100的正确字节)

$ cat text | ./a.out 
Seek moved to this position: -1
Seek said: Illegal seek
Then read read 5 bytes
The bytes read were '# def'
Run Code Online (Sandbox Code Playgroud)

(那些字节是文件的前5个字节)


我还注意到标准输入版本是你说的正常工作.如果您遇到FILE *版本问题,我怀疑fopen()调用失败,因此请务必检查返回值fopen().当然,你总是可以这样做:

FILE *fr = stdin;  
Run Code Online (Sandbox Code Playgroud)

因此,您正在阅读标准版.然而,由于您不能总是寻求标准版,我建议您在计划寻找时始终打开文件.

请注意,您无法在所有可以打开文件的设备上寻找(尽管在大多数系统上都没有问题),因此您应该始终检查a的结果seek()以确保它成功.