2012-02-11 26 views
2

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

所以我的代码是:

#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个可用空间剩下的所有字节,对吧?我怎样才能防止这种情况发生?

回答

2

它看起来像你期待

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

以某种方式积累的东西缓冲。它没有。随后的每一个read都会将它在缓冲区开始时读取的任何内容覆盖前面的read已读取的内容。

你需要把你的writewhile块 - 一个写为每读取,只有write就像你read,否则你会写垃圾(从calloc和/或剩菜零前面读)在你的日志文件中。

另外请注意,虽然你的技术可能大部分时间工作的行缓冲输入流,但它不会做你所期望的,如果你从文件或管道重定向。您应该使用格式化的输入功能(如getline,如果您的实施具有该功能,则可使用scanffgets)。

+0

我知道这是一种脱离主题,但这些开放/读取/写入功能到底是什么,他们在哪里定义?他们似乎与他们的fread e.t.c相似。同行。 – Lefteris 2012-02-11 10:49:58

+0

'read'和'write'在''中,''打开'在''中。 'man 2 open'来查看手册页 - 第2部分:系统调用。 – Mat 2012-02-11 10:54:16

+0

谢谢,现在就去看看吧 – Lefteris 2012-02-11 10:55:17