【问题标题】:I/O issues writing on file写入文件的 I/O 问题
【发布时间】:2012-02-11 10:41:13
【问题描述】:

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

所以我的代码是:

#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's。我猜 \00 代表 1024 可用的所有空字节,对吧?我怎样才能防止这种情况发生?

【问题讨论】:

    标签: c io system-calls


    【解决方案1】:

    看起来你在期待

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

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

    您需要将 write 放入 while 块中 - 每次读取一次写入,并且只写入 writeread 一样多,否则您将写入垃圾(calloc 中的零和/或上次读取的剩余部分)在您的日志文件中。

    另外请注意,虽然您的技术可能大部分时间都适用于行缓冲输入流,但如果您从文件或管道重定向,它不会达到您期望的效果。你应该使用格式化的输入函数(比如getline,如果你的实现有,scanf,或fgets)。

    【讨论】:

    • 我知道这有点离题,但这些打开/读/写函数到底是什么,它们在哪里定义?他们似乎很像他们的 fread 等。同行。
    • readwrite&lt;unistd.h&gt; 中,open&lt;fcntl.h&gt; 中。 man 2 open 查看手册页 - 第 2 节:系统调用。
    • @Mat 谢谢你的建议,我有这样的误解,即读取必须在写入之前在缓冲区中积累东西,所以我很高兴你为我清除了它。如果可以的话,我还有另一个问题。只要我在不点击返回按钮的情况下输入句子,日志记录就会完美无缺,但如果我需要点击它,之前的一些句子也可能会被记录下来。在我按 Enter 键写入日志文件之前,是否需要以某种方式清理缓冲区?
    • 不,你不需要清除任何东西,但你必须确保你写的和你读的一样多。 readBytes 应该出现在您的 write 调用中,而不是 SIZE
    • @Mat 我刚刚尝试了您的建议,但问题似乎仍未解决。我以这种方式修改了我的代码:while (readBytes = read(0, buffer, SIZE)&amp;&amp;(strncmp(buffer, "stop", 4) != 0)) { while ((writBytes = write(fd, buffer, SIZE)) &lt; readBytes); },但仍然记录了以前句子中不需要的字符串。
    猜你喜欢
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-20
    相关资源
    最近更新 更多