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;