C процесс, созданный с помощью popen, не выводит вывод - PullRequest
1 голос
/ 07 мая 2020

Мне в качестве домашнего задания нужно решить следующую задачу: создать два процесса с помощью popen. Родительский процесс будет читать строки стандартного ввода длиной не более 30 символов и давать первому дочернему элементу цифры из строки, а второму дочернему элементу - буквы из строки, которые преобразуют их в верхний регистр. Оба процесса затем будут выводить эти данные на стандартный вывод родительского объекта. В общем, я хочу что-то похожее на запуск команды «tee». Прочтите строку, напишите какой-нибудь вывод и повторяйте, пока не ctrl-d

Вот моя попытка:

#include <stdio.h>
#include <ctype.h>

int main() {
    FILE *digits, *letters;
    char string[31];

    if ((digits = popen("tee", "w")) == NULL) {
        perror("can't create pipe for digits");
        return 1;
    }

    if ((letters = popen("tr a-z A-Z", "w")) == NULL) {
        perror("can't create pipe for letters");
        return 1;
    }

    while(!feof(stdin)) {
        fgets(string, 31, stdin);
        for (char* c = string; *c != '\0'; c++)
            if (isdigit(*c))
                fputc(*c, digits);
            else if (isalpha(*c))
                fputc(*c, letters);
        fputc('\n', digits);
        fputc('\n', letters);
    }
    pclose(digits);
    pclose(letters);
    return 0;
}

Но после того, как я напишу строку и нажму Enter, программа снова ожидает ввода, без печать чего угодно. Он печатает весь вывод в конце после нажатия ctrl-d. И я не понимаю почему. Он правильно считывает строку, затем подает правильные символы каждому дочернему элементу, за которым следует новая строка. Почему эти процессы сразу не распечатывают свой результат? Выполняется ли фактическая команда при вызове pclose? Потому что я не мог найти никакой информации об этом. Кроме того, написание '\ n' в стандартный ввод дочернего элемента - это то же самое, что нажатие клавиши Enter? И что еще более странно, так это то, что последняя строка вывода каждого дочернего элемента печатается дважды.

Например, вот как я бы хотел, чтобы это работало:

(input)
1a2b3c
(output)
123
ABC
(input)
4d5e6f
(output)
456
DEF
(ctrl-d)

Но я получаю это:

(input)
1a2b3c
(input)
4d5e6f
(ctrl-d)
(output)
123
456
456
ABC
DEF
DEF
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...