#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <stdint.h>
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;
}
The Output is as follows:
输出如下:
This is a test file��
这是一个测试文件
0
his is a test file
他是一个测试文件
��
testfile.txt :
This is a test file Testing how SEEK_END works This is a test file
这是一个测试文件测试SEEK_END的工作原理这是一个测试文件
I have tried different formatting for offset, such as %ld,%d, but the output is still the same. Can't figure out why garbage appears at the end of first line and last line. Please help.
我尝试了不同的偏移格式,例如%ld,%d,但输出仍然相同。无法弄清楚为什么垃圾出现在第一行和最后一行的末尾。请帮忙。
3 个解决方案
#1
3
You need to leave room for an end of line character, '\0';
你需要为行尾字符留出空间,'\ 0';
So make char buffer[19];
char buffer[20];
then also add buffer[19] = '\0';
- remember it's zero based counting. Then it shouldn't have the garbage data.
所以make char buffer [19]; char buffer [20];然后还添加缓冲区[19] ='\ 0'; - 记住它是基于零的计数。然后它不应该有垃圾数据。
The reason is because printf doesn't know where the end is of the character array. So it keeps printing until it finds a '\0' in garbage memory.
原因是因为printf不知道字符数组的结尾。所以它一直打印,直到它在垃圾记忆中找到'\ 0'。
#2
2
read does not know anthing about strings, it reads bytes from a file. so if you read in 19 bytes into "buffer" and there is no terminating \0 then it is not a valid string.
read不知道关于字符串的anthing,它从文件中读取字节。因此,如果您将19个字节读入“缓冲区”并且没有终止\ 0那么它就不是有效的字符串。
So either you need to ensure that your buffer is 0 terminated or print out only the first 19 bytes e.g. printf( "%.*s", sizeof(buffer), buffer );
or extend the buffer for the \0 e.g. char buffer[20] = {0};
因此,您需要确保缓冲区为0终止或仅打印出前19个字节,例如printf(“%。* s”,sizeof(缓冲区),缓冲区);或扩展\ 0的缓冲区,例如char buffer [20] = {0};
You should also open the file like this in order to make sure lseek works (file must be opened in binary mode)
您还应该打开这样的文件,以确保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;
}
it is always good to give an error message when something fails instead of just terminating the program.
当出现故障而不是仅仅终止程序时,给出错误消息总是好的。
#3
0
Other answers have already offered solutions for the problem with printing buffer
. This answer addresses the other question in your post.
其他答案已经为打印缓冲区的问题提供了解决方案。这个答案解决了你帖子中的另一个问题。
Due to operator precedence, the line
由于运算符优先,该行
if(offset = lseek(file,-19,SEEK_END) < 0) return 1;
is equivalent to:
相当于:
if(offset = (lseek(file,-19,SEEK_END) < 0)) return 1;
I am sure you meant to use:
我相信你打算使用:
if( (offset = lseek(file,-19,SEEK_END)) < 0) return 1;
#1
3
You need to leave room for an end of line character, '\0';
你需要为行尾字符留出空间,'\ 0';
So make char buffer[19];
char buffer[20];
then also add buffer[19] = '\0';
- remember it's zero based counting. Then it shouldn't have the garbage data.
所以make char buffer [19]; char buffer [20];然后还添加缓冲区[19] ='\ 0'; - 记住它是基于零的计数。然后它不应该有垃圾数据。
The reason is because printf doesn't know where the end is of the character array. So it keeps printing until it finds a '\0' in garbage memory.
原因是因为printf不知道字符数组的结尾。所以它一直打印,直到它在垃圾记忆中找到'\ 0'。
#2
2
read does not know anthing about strings, it reads bytes from a file. so if you read in 19 bytes into "buffer" and there is no terminating \0 then it is not a valid string.
read不知道关于字符串的anthing,它从文件中读取字节。因此,如果您将19个字节读入“缓冲区”并且没有终止\ 0那么它就不是有效的字符串。
So either you need to ensure that your buffer is 0 terminated or print out only the first 19 bytes e.g. printf( "%.*s", sizeof(buffer), buffer );
or extend the buffer for the \0 e.g. char buffer[20] = {0};
因此,您需要确保缓冲区为0终止或仅打印出前19个字节,例如printf(“%。* s”,sizeof(缓冲区),缓冲区);或扩展\ 0的缓冲区,例如char buffer [20] = {0};
You should also open the file like this in order to make sure lseek works (file must be opened in binary mode)
您还应该打开这样的文件,以确保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;
}
it is always good to give an error message when something fails instead of just terminating the program.
当出现故障而不是仅仅终止程序时,给出错误消息总是好的。
#3
0
Other answers have already offered solutions for the problem with printing buffer
. This answer addresses the other question in your post.
其他答案已经为打印缓冲区的问题提供了解决方案。这个答案解决了你帖子中的另一个问题。
Due to operator precedence, the line
由于运算符优先,该行
if(offset = lseek(file,-19,SEEK_END) < 0) return 1;
is equivalent to:
相当于:
if(offset = (lseek(file,-19,SEEK_END) < 0)) return 1;
I am sure you meant to use:
我相信你打算使用:
if( (offset = lseek(file,-19,SEEK_END)) < 0) return 1;