read()调用后printf打印垃圾。 偏移始终打印为0

#include  #include  #include  #include  #include  int main() { int file; off_t offset; if((file=open("testfile.txt",O_RDONLY)) < -1) return 1; char buffer[19]; if(read(file,buffer,19) != 19) return 1; fprintf(stdout,"%s\n",buffer); if(offset = lseek(file,-19,SEEK_END) < 0) return 1; fprintf(stdout,"%jd\n",(intmax_t)offset); if(read(file,buffer,19) != 19) return 1; fprintf(stdout,"%s\n",buffer); return 0; } 

输出如下:

这是一个测试文件

0

他是一个测试文件

testfile.txt:

这是一个测试文件测试SEEK_END的工作原理这是一个测试文件

我尝试了不同的偏移格式,例如%ld,%d,但输出仍然相同。 无法弄清楚为什么垃圾出现在第一行和最后一行的末尾。 请帮忙。

你需要为行尾字符留出空间,’\ 0′;

所以make char buffer[19]; char buffer[20]; 然后还添加buffer[19] = '\0'; – 记住它是基于零的计数。 然后它不应该有垃圾数据。

原因是因为printf不知道字符数组的结尾。 所以它一直打印,直到它在垃圾记忆中找到’\ 0’。

read不知道关于字符串的anthing,它从文件中读取字节。 因此,如果您将19个字节读入“缓冲区”并且没有终止\ 0那么它就不是有效的字符串。

因此,您需要确保缓冲区为0终止或仅打印出前19个字节,例如printf( "%.*s", sizeof(buffer), buffer ); 或扩展\ 0的缓冲区,例如char buffer[20] = {0};

您还应该打开这样的文件,以确保lseek工作(文件必须以二进制模式打开)

 if((file=open("testfile.txt",O_RDONLY|O_BINARY)) == -1) // returns -1 by failure { perror("testfile.txt"); // to get an error message why it failed. return 1; } 

当出现故障而不是仅仅终止程序时,给出错误消息总是好的。

其他答案已经为打印buffer的问题提供了解决方案。 这个答案解决了你post中的另一个问题。

由于运算符优先,该行

 if(offset = lseek(file,-19,SEEK_END) < 0) return 1; 

相当于:

 if(offset = (lseek(file,-19,SEEK_END) < 0)) return 1; 

我相信你打算使用:

 if( (offset = lseek(file,-19,SEEK_END)) < 0) return 1;