Scanf в то время как цикл не может ничего вводить - PullRequest
0 голосов
/ 11 мая 2019

Я использую виртуальную машину Linux 2.0.26, и у меня никогда не возникало этой проблемы.

Цикл while работает, потому что я добавил в него printf для его проверки.

#include <stdio.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

void main()
{
    int i;

    mknod("pipe.txt", S_IFIFO | 0666, 0);
    for (i = 0; i < 2; i++) {
        if (fork() == 0) {
            if (i == 0)
                to_pipe();
            //else
            //    pipe_a_archivo();
        }
    }
    wait(NULL);
    unlink("pipe.txt");
}

void to_pipe()
{
    int num, fdini;

    fdini = open("pipe.txt", O_WRONLY);
    do {
        //printf("Test");
        scanf("%d", &num);
        write(fdini, &num, sizeof(int));
    } while (num != 0);

    close(fdini);
    unlink("pipe.txt");
    exit();
}

Эта программа должна получать цифры с клавиатуры и записывать их в файл.Моя проблема заключается в том, что всякий раз, когда я запускаю программу из командной строки, ничего не происходит, scanf() не работает, потому что не позволяет мне вводить любое число.Я точно знаю, что цикл работает, потому что если раскомментировать printf(), он печатает на экране.Любая помощь в решении этой проблемы?

1 Ответ

0 голосов
/ 12 мая 2019

Я думаю, что большая часть вашей проблемы связана с тем, что вы не используете функцию pipe_a_archivo() для чтения из FIFO и записи данных в файл. Конечно, код в вопросе не является хорошим MCVE ( Minimal, Complete, Verifiable Example ). Среди других проблем нет действия для второй итерации цикла.

Эта ошибка кода проверяет вызовы функций и включает вероятную реализацию pipe_a_archivo(), а затем работает разумно:

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>

static void to_pipe(void);
static void pipe_a_archivo(void);

#define FIFO_NAME "pipe.txt"
#define FILE_NAME "archive.txt"

int main(void)
{
    if (mkfifo(FIFO_NAME, 0666) != 0)
    {
        fprintf(stderr, "failed to create FIFO '%s'\n", FIFO_NAME);
        exit(EXIT_FAILURE);
    }
    if (fork() == 0)
        to_pipe();
    if (fork() == 0)
        pipe_a_archivo();
    int corpse;
    int status;
    while ((corpse = wait(&status)) > 0)
        printf("PID %d exited with status 0x%.4X\n", corpse, status);
    unlink("pipe.txt");
}

static void to_pipe(void)
{
    int num, fdini;

    fdini = open(FIFO_NAME, O_WRONLY);
    do
    {
        printf("Enter a number: ");
        fflush(stdout);
        scanf("%d", &num);
        write(fdini, &num, sizeof(int));
    } while (num != 0);

    close(fdini);
    exit(0);
}

static void pipe_a_archivo(void)
{
    int fd_in = open(FIFO_NAME, O_RDONLY);
    if (fd_in < 0)
    {
        fprintf(stderr, "Failed to open FIFO '%s' for reading\n", FIFO_NAME);
        exit(EXIT_FAILURE);
    }

    FILE *fp_out = fopen(FILE_NAME, "w");
    if (fp_out == NULL)
    {
        fprintf(stderr, "Failed to open file '%s' for writing\n", FILE_NAME);
        exit(EXIT_FAILURE);
    }

    int num;
    while (read(fd_in, &num, sizeof(num)) == sizeof(num))
    {
        fprintf(fp_out, "%d\n", num);
    }

    close(fd_in);
    fclose(fp_out);
    exit(0);
}

Я удалил цикл в main(), потому что цикл, который проверяет, на какой итерации он находится, а затем вызывает соответствующую функцию, на самом деле не очень хороший дизайн. Этот код также удаляет только FIFO в основной программе и только после выхода из обоих дочерних процессов.

Пример прогона:

$ ./fifo29
Enter a number: 23
Enter a number: 34
Enter a number: 12931344
Enter a number: 0
PID 10939 exited with status 0x0000
PID 10940 exited with status 0x0000
$ cat archive.txt
23
34
12931344
0
$
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...