scanf在while循环中无法输入任何内容

时间:2019-05-11 20:22:55

标签: c linux

我使用的是Linux 2.0.26 VM,从来没有这个问题。

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 :(得分:0)

我认为您的大部分问题是由于您没有实现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
$