I / O问题写入文件

时间:2012-02-11 10:41:13

标签: c io system-calls

我很难弄清楚为什么这段代码不能正常工作。我正在学习I / O操作的基础知识,我必须想出一个C程序,它在'log.txt'文件中写入从标准输入中给出的内容,并且当输入'stop'字时,程序必须停止

所以我的代码是:

#include "main.h"
#define SIZE 1024

int main(int argc, char *argv[])
{
    int fd;
    int readBytes;
    int writBytes;
    char *buffer;

    if ((fd = open("log.txt", O_WRONLY|O_APPEND)) < 0) 
    {
        perror("open");
    }

    buffer = (char *) calloc (SIZE, sizeof(char));
    while ((readBytes = read(0, buffer, SIZE) < SIZE)&&(strncmp(buffer, "stop", 4) != 0));

    if ((writBytes = write(fd, buffer, SIZE)) < 0)
    {
        perror("write");
    }

    if ((close(fd)) < 0) 
    {
        perror("close");
    }
}

如果我输入:

this is just a text
stop

输出

stop
is just a text

如果我输入的不仅仅是一句话:

this is just a text
this is more text
and text again
stop

这是记录的内容:

stop
ext again
xt
t

最重要的是,如果我尝试从vim或只是文本编辑器编辑log.txt文件,我可以看到'\ 00'。我猜\ 00代表1024可用的所有剩余字节,对吧?我该如何防止这种情况发生?

1 个答案:

答案 0 :(得分:2)

看起来你期待

readBytes = read(0, buffer, SIZE) < SIZE)

以某种方式积累缓冲区中的东西。它没有。每个后续的read都会将它在缓冲区开头读取的内容放入其中,覆盖之前read已读取的内容。

您需要将write放在while块中 - 每次阅读都写一次,而write只需要read,否则你会写日志文件中的垃圾(来自calloc的零和/或上一次读取的剩余部分)。

另请注意,尽管您的技术大部分时间都可能用于行缓冲输入流,但如果从文件或管道重定向,它将无法满足您的预期效果。您应该使用格式化的输入函数(例如getline,如果您的实现有scanffgets)。