Проблемы ввода-вывода при записи в файл - PullRequest
2 голосов
/ 11 февраля 2012

Мне трудно понять, почему этот кусок кода не работает так, как должен.Я изучаю основы операций ввода-вывода, и мне нужно придумать программу на 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

И вдобавок ко всему, если я попытаюсь отредактировать файл log.txt из vim или просто текстового редактораЯ вижу "00".Я думаю, что \ 00 означает все байты, оставшиеся пустыми из 1024 доступных, верно?Как я могу предотвратить это?

1 Ответ

2 голосов
/ 11 февраля 2012

Похоже, вы ожидаете

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

чтобы как-то накапливать вещи в буфере. Это не так. Каждый последующий read помещает все прочитанное в начало буфера, перезаписывая то, что прочитал предыдущий read.

Вам нужно поместить write в блок while - по одной записи на каждое чтение, и только write столько же, сколько вам read, в противном случае вы будете писать мусор (нули из calloc и / или остатки от предыдущего чтения) в файле журнала.

Также обратите внимание, что, хотя ваш метод, вероятно, будет работать большую часть времени для входного потока с буферизацией строки, он не будет делать то, что вы ожидаете, если вы перенаправляете из файла или канала. Вы должны использовать отформатированные функции ввода (например, getline, если у вашей реализации это есть, scanf или fgets).

...