C 为什么我在读取txt文件时会得到笑脸字符?

C 为什么我在读取txt文件时会得到笑脸字符?,c,fopen,C,Fopen,我试图不断地读取文本文件,但我不知道我在这里做错了什么。它一直在给我打印一些不可打印的ascii字符 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <signal.h> #include <fcntl.h> #include <errno.h> #include <sys/typ

我试图不断地读取文本文件,但我不知道我在这里做错了什么。它一直在给我打印一些不可打印的ascii字符

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include "windows.h"

int main(int argc, char **argv)
{
    int n, fd;
    char buff[256];
    if (argc != 2)
    {
        fprintf(stderr, "usage: %s <filename>\n", argv[0]);
        return 1;
    }

    fd = open(argv[1], O_RDONLY);
    if (fd < 0)
    {
        perror("open");
        return 1;
    }
    else if (lseek(fd, 0, SEEK_END) < 0)
    {
        perror("lseek");
        return 1;
    }
    else
    {
        while (1)
        {
            n = read(fd, buff, sizeof(buff));
            if (n < 0)
            {
                perror("read");
                break;
            }
            if (n == 0)
            {
                puts(buff);
                Sleep(100);
                continue;
            }
            if (write(STDOUT_FILENO, buff, n) < 0)
            {
                perror("write");
                break;
            }
        }   
    }
    return 0;
}
输出如下:

foo-12-

问题在于线路:

puts(buff);
read()
返回
0
时,表示您已到达文件的末尾,因此没有要打印的内容。在循环的上一次迭代中,您已经在以下行打印了文件的内容:

write(STDOUT_FILENO, buff, n)
put()
正在打印
buff
中的任何垃圾。由于
buff
不是以null结尾的,因此它可能会在远远超过数组末尾的位置继续打印,直到找到一个null字节

摆脱那条线

您不打印文件内容的原因是因为在开始时您执行了以下操作:

lseek(fd, 0, SEEK_END)

这将在文件尝试读取任何内容之前到达文件的末尾。因此,您的程序将仅显示启动程序后添加到文件中的内容。由于
sleep(100)
,它将等待100秒,然后再打印下一个块。

主要问题是
lseek()
将文件指针放在文件末尾

然后,所有后续的读取操作都试图读取超过文件结尾的内容

实际上没有读取任何内容,因此输入缓冲区不变

建议删除对
lseek()
的调用,以便使用调用
open()
(将文件指针放在文件开头)的结果

然后调用
read()
将正确地获得文件内容的连续块

这行:
if(n==0)
表示,如果没有读取任何内容。但是,从read()返回的0表示“文件结束”。因此,您真正想要的是
if(n>0)
,这意味着从文件中读取了一些字节

行:
put(buff)将仅输出字符。但是,
read()
不会以NUL字节终止输入缓冲区,因此对puts()的调用可能会输出超过buff[]数组末尾的字符,从而导致未定义的行为


强烈建议1)在read()之后插入buff[n]='\0'或2)使用fgets()从缓冲区中读取行,因为fgets()会在缓冲区中附加NUL字节。

读取的文件是什么?为什么要调用
put(buff)
read
返回
0
?@ameyCU我在另一个进程中将文件名作为参数传递。请看我上面提到的示例文件内容,即
foo-12-
@Barmar,这应该是我需要显示读取内容的地方。在这一点上我错了吗?您显示了用
write(STDOUT\u FILENO,buff,n)
删除行
put(buff)
行只清除了您正确猜测来源的垃圾。“显示读取内容”的问题仍然没有答案。我还替换了
if(write(STDOUT\u FILENO,buff,n))
块,并替换为
put
语句,但仍然没有成功。您不应该使用
put()
。这是用于打印字符串的,
buff
不是字符串。就是这样。谢谢:)当你把它放进节目里的时候,你在想什么?如果你想打印文件内容,为什么要先打印到最后呢?嗯,我需要每半秒钟监控一个文本文件。这就是我最初想到的。虽然你解决了上述问题的谜团,但我的代码仍然无法处理txt文件中的动态变化,即文本文件得到更新,但我上面的代码仍然显示了过时的文本,这是一个错误x-(