Как мне получить ввод с клавиатуры от пользователя, используя C и linux? - PullRequest
0 голосов
/ 06 мая 2020

Мне нужно создать короткую программу, которая создает два дочерних процесса, каждый из которых принимает целое число с клавиатуры и записывает их в конвейер, откуда родительский процесс суммирует их и отображает результат на экране.

Я написал один с помощью scanf (), но он зависает и не дает мне суммы. Как мне заставить его работать с scanf или любым другим способом, если это возможно?

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int pipe(int pd[2]);
int main(int argc, char *argv[])
{

    int pd[2], sum=0, num=0;
    if(pipe(pd) == -1)
    for(int i = 0; i < 2; i++)
    {
        if(fork() == 0)
        {
            scanf("%d", num);
            if(write(pd[1], &num, sizeof(int)) == -1)
                printf("Error: Write()");           
        }
    }

    for(int j = 0; j < 2; j++)
    {
        wait(NULL);
        if(read(pd[0], &num, sizeof(int)) == -1)
            printf("Error: Read()");

        sum += num;
    }
    printf("Total: %d\n", sum);
}

1 Ответ

1 голос
/ 06 мая 2020

Здесь много проблем:

  • У вас есть if(pipe(pd) == -1), и я предполагаю, что вы хотели иметь обработчик ошибок в качестве предложения «then» для этого, но у вас его нет, поэтому дети будет появляться только в случае отказа канала, что в основном противоположно тому, что вы хотите.
  • У вас есть scanf("%d", num);. Вам нужно &num, поскольку num еще не является указателем.
  • Вам нужно return или exit из дочерних процессов, иначе они попадут в следующий l oop и потребляют вывод.

Если исправлены только эти вещи, этого достаточно, чтобы заставить его работать:

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int pipe(int pd[2]);
int main(int argc, char *argv[])
{

    int pd[2], sum=0, num=0;
    if(pipe(pd) == -1)
    {
        perror("pipe");
        return 1;
    }
    for(int i = 0; i < 2; i++)
    {
        if(fork() == 0)
        {
            scanf("%d", &num);
            if(write(pd[1], &num, sizeof(int)) == -1)
                printf("Error: Write()");
            return 0;
        }
    }

    for(int j = 0; j < 2; j++)
    {
        wait(NULL);
        if(read(pd[0], &num, sizeof(int)) == -1)
            printf("Error: Read()");

        sum += num;
    }
    printf("Total: %d\n", sum);
}

Есть еще несколько вещей, которые вы тоже должны исправить, но они не полные шоу-стопперы. Вот что мне бросилось в глаза:

  • Вам не нужно объявлять свой собственный pipe прототип. Один из unistd.h подойдет.
  • Вы должны обработать случай, когда fork или scanf завершится ошибкой.
  • Вы должны обработать частичное чтение и запись.
  • После разветвления вы должны закрыть конец чтения канала в дочерних элементах и ​​конец записи канала в родительском элементе. Буферизация линии TTY для надежной работы.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...