0
#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;
}

输出如下:

这是一个测试文件��

0

他是一个测试文件

��

测试文件.txt:

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

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

4

3 回答 3

3

您需要为行尾字符“\0”留出空间;

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

原因是 printf 不知道字符数组的结尾在哪里。所以它会一直打印,直到它在垃圾内存中找到一个'\0'。

于 2014-11-11T06:05:42.713 回答
2

read 对字符串一无所知,它从文件中读取字节。因此,如果您将 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;
}

当某些事情失败时给出错误消息而不是仅仅终止程序总是好的。

于 2014-11-11T06:16:36.393 回答
0

其他答案已经为打印问题提供了解决方案buffer。该答案解决了您帖子中的另一个问题。

由于运算符优先级,该行

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;
于 2014-11-11T06:31:23.560 回答