【问题标题】:How to clear the contents of scanf of a stopped process?如何清除已停止进程的scanf内容?
【发布时间】:2014-09-15 12:05:00
【问题描述】:

我正在使用 fork,子进程在 for 循环中使用 scanf 从用户那里读取数据十次。然而,父进程在睡眠 4 秒后向子进程发送 SIGSTOP 信号,并从用户那里读取一个值并打印它。但是,如果用户在子进程中输入了数据但没有为 scanf 按下回车键,则父进程读取但打印写入子进程中的数据。我该如何阻止这种情况发生。

ch=fork();
if(ch==0)
{
    for(i=0;i<10;i++)
    {
        fflush(stdin);
        scanf("%s",buf);
        printf("%d: %s\n",i,buf);
    }
}
else
{
    char buf2[100],cha;
    sleep(4);
    kill(ch,SIGSTOP);
    write(STDOUT_FILENO,"\nchld stopped\n",14);
    memset(stdin,0,sizeof(stdin));
    read(STDIN_FILENO,buf2,2);
    write(STDOUT_FILENO,buf2,2);

    kill(ch,SIGCONT);
    wait(SIGCHLD);
}

所以输出例如是这样的:

一个

0: 一个

b

1: b

ac(这里我不按回车键等待 SIGSTOP)

chld 停止

tr(为父级输入数据并按下回车键)

ac2: tr

c

3: c ...等等

那么输入tr后为什么我的父母显示ac?

【问题讨论】:

    标签: c fork flush memset fflush


    【解决方案1】:

    fflush(stdin) 从来都不是正确的做法,尽管很多人都尝试过。 fflush 仅用于输出。你的memset 是纯粹的精神错乱。 wait 的参数不应该是信号号——它甚至不是正确的类型,所以你应该得到一个你显然忽略的警告。

    这些都是简单的错误。您正在尝试做的事情存在更深层次的概念问题。

    由于您没有修改任何 tty 设置,因此 tty 在您的程序运行时处于规范模式。这意味着 tty 处理行编辑(退格、Ctrl-U、Ctrl-W 等)并且在行终止之前不会向程序发送任何内容。

    当您键入部分行时,该部分行不在标准输入缓冲区中。它在 tty 缓冲区中。它还不属于任何进程。这就是为什么您的父进程可以读取在孩子尝试阅读时部分输入的行。孩子从来没有得到过任何东西。

    要清空 tty 缓冲区,应该可以:关闭规范模式;设置非阻塞模式;读入 a 直到发生错误(当 tty 没有任何东西可以给你时,EAGAIN/EWOULDBLOCK 将在非阻塞模式下发生);重新打开阻塞和规范模式。这个想法是消耗当前可用的任何东西,而无需等待更多。执行各个步骤的代码应该很容易找到。

    一般来说,我质疑为用户提供输入信息的机会的界面是否明智,然后自发地中断对该信息的阅读以阅读其他内容。这将导致用户在辅助输入提示下大喊:嘿!我在这里打字!

    【讨论】:

    • 好的...但是你能告诉我如何清除 tty 缓冲区吗?
    【解决方案2】:

    好的,我找到了解决方案。

    我使用了 tcflush():刷新未传输的输出数据,未读取的输入数据,或两者兼而有之。

    tcflush(STDIN_FILENO,TCIFLUSH);在父级读取之前的行。

    我在这里找到了解决方案... How can I flush unread data from a tty input queue on a UNIX system?

    【讨论】:

      【解决方案3】:

      这是因为 read(), write() 函数。当您输入内容而不按回车键时。它将在 stdinput 中,无论在 stdinput 中,它将由 read() 函数存储在您的示例中指定的 buf2 中读取。无论在 buf2 中,它都会通过 write() 发送到 stdoutput。您可以在注释 read()、write() 函数或仅打印“buf2”时看到差异。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-07-16
        • 1970-01-01
        • 2016-05-22
        • 1970-01-01
        • 2019-05-12
        • 2010-12-19
        • 2019-11-13
        相关资源
        最近更新 更多