/ / C - stdin, potok unix i EOF - c, potok, c99

C - stdin, potok unix i EOF - c, pipe, c99

Piszę aplikację, która najpierw odbieradane z potoku unix, a następnie monitowanie użytkownika o dane wejściowe. Wydaje mi się, że nie mogę zrozumieć, dlaczego dane wejściowe z potoku wydają się nie zamykać poprawnie przed monitowaniem użytkownika o wprowadzenie danych. Wydaje mi się, że brakuje mi czegoś bardzo podstawowego.

Wypróbowałem wszystkie przedstawione przykłady flushingu stdin tutaj bezskutecznie. To wydaje się również potencjalnie istotna, ale nie udało mi się uzyskać żadnych istotnych odpowiedzi.

#include <stdio.h>
#include <stdlib.h>

#define BUFSZ 1024

int main(void) {

char *buf = calloc(BUFSZ, sizeof(char));

while(fgets(buf, BUFSZ, stdin)) { printf("Pipe input: %s", buf); }

printf("Enter input: ");
fgets(buf, BUFSZ, stdin);
printf("User input: %s", buf);

free(buf);
return 0;
}

Przykładowe użycie i wyjście:

$ cat testdata2 | ./a.out
Pipe input: testdata testdata
Pipe input: testdata testdata2
Pipe input: testdata testdata3
Pipe input: testdata testdata4
Pipe input: testdata testdata5
Pipe input: testdata testdata6
Pipe input: testdata testdata7
Enter input: User input: testdata testdata7
$

Jak to możliwe, że drugie fgets () (przeznaczone na klawiaturę) nigdy nie dotyka bufora?

Ten MCVE został skompilowany przetestowany na OSX i Linux z identycznymi wynikami.

Odpowiedzi:

5 dla odpowiedzi № 1

Gdyby stdin jest więc fajką stdin nie jest terminalem. Kiedy dojdziesz do końca rury, to jest to! To koniec stdin. Oczekujesz jakiejś magicznej transformacji stdin przestaje być fajką i zaczyna być czymśjeszcze. Nie spodziewaj się tego. To wciąż fajka. I wystąpił EOF. W przypadku rur EOF jest stanem trwałym. Kiedy już uderzysz EOF, nigdy więcej nie dostaniesz.

Sprawdź wartość zwracaną fgets każdy czas. Zobaczysz, że ostatni zwraca wartość NULL, ponieważ jest w EOF.

Programy, które chcą czytać potokowane stdin a także uzyskać wejście klawiatury musi otworzyć terminal oddzielnie, jak w FILE *tty = fopen("/dev/tty", "r");