Вопрос по pipe, c, stdin, stdout – Чтение из трубопровода строка за строкой в C

8

Как я могу отделить линии, идущие от трубы. В трубе есть этот текст:

HALLO:500\n
TEST:300\N
ADAD
ADAWFFA
AFAGAGAEG

Я хочу отделить строки от трубы, потому что я хочу сохранить значения в переменных.

Вот мой код c:

#include 
#include 

#define BUFFERSIZE    1

int main(int argc, char **argv){
    unsigned char     buffer[BUFFERSIZE];
    FILE                         *instream;
    int                            bytes_read=0;
    int                            buffer_size=0;


    buffer_size=sizeof(unsigned char)*BUFFERSIZE;
    /* open stdin for reading */
    instream=fopen("/dev/stdin","r");

    /* did it open? */
    if(instream!=NULL){
        /* read from stdin until it's end */
        while((bytes_read=fread(&buffer, buffer_size, 1, instream))==buffer_size){
            fprintf(stdout, "%c", buffer[0]);
        }
    }
    /* if any error occured, exit with an error message */
    else{
        fprintf(stderr, "ERROR opening stdin. aborting.\n");
        exit(1);
    }

    return(0);
}

Это правильный способ чтения из трубы для лучшей построчно?

замещатьfread с .fgets Anish Ramaswamy
for the best это субъективный вопрос. Вы действительно сталкиваетесь с какой-либо проблемой? abasu

Ваш Ответ

2   ответа
14

чтение со стандартного ввода, Программа не должнаНе имеет значения, является ли ввод каналом, перенаправленным файлом или клавиатурой.

fread будет просто читать, пока буфер не заполнится. Используйте fgets, чтобы прочитать строку.

Также размер буфера должен быть достаточно большим, чтобы вместить строку. Для маленьких одноразовых программ вы можете просто выбрать номер. Или тамстандартное имяBUFSIZ который дает вамдовольно большой буфер. Насколько велик? Достаточно большой. В самом деле? Наверное.

fgets скопирует символ новой строки в строке, если строка не заполняется первой. Таким образом, вы можете проверить последний символ, чтобы определить, была ли строка обрезана или нет. При разумном вкладе этоне произойдет. Но более надежный подход выделил бы больший буфер, скопировал бы неполную строку и вызвал быfgets снова тп продолжать пытаться получить полную линию.

#include <stdio.h>

int main() {
    char buf[BUFSIZ];
    fgets(buf, sizeof buf, stdin);
    if (buf[strlen(buf)-1] == '\n') {
        // read full line
    } else {
        // line was truncated
    }
    return 0;
}
</stdio.h>

Это делает вас на полпути к защите от страшныхпереполнение буфера проблема.fgets не будет писать больше, чем переданный ему размер. Другая половина, как упомянуто выше, делает что-то разумное с возможными частичными строками, которые могут быть результатом неожиданно длинных входных строк.

Да, это так. Я смотрю на руководство и надеюсь, что до полудня я исправлю свою проблему bladepit
Я не пытаюсь звучать сопливым. Я действительно так думаюдля меня лучше не писать такой пример. luser droog
Вам необходимо указать максимальную длину. Это остановится на новой строке. О хорошо, ядобавлю больше к ответу. Но у вас всегда должны быть установлены manpages. Oни'супер полезно. luser droog
хорошо, у тебя был хороший пример использования fgets? bladepit
1

s другой вариант (я не совсем уверен, что этособственно» way) - использовать количество байтов, прочитанныхread функция. В этом примере я читал изstdin хотя перенаправление было сделано, поэтому fd в 0 - это файл / труба / все, что вам нужно.

  while ((nbytes=read(STDIN_FILENO, buffer, MAX_PIPE_SIZE)) > 0) {
    write(STDOUT_FILENO, buffer, nbytes);
  }

Похожие вопросы