猫打破了程序,手动标准输入不

秋野野

我有这个小程序:

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

int main() {
    int orig = 1;
    for (int i = 0; (i != 3) && orig; ++i) {
        orig = orig && fork();
    }
    if (orig) {
        for (int i = 0; i != 3; ++i) {
            wait(NULL);
        }
    } else {
        int num;
        scanf("%8d", &num);
        printf("%d\n", num*num);
    }
}

它应该只是对从中读取的三个数字求平方stdin如果我自己输入数字,它会起作用:

akiiino$ ./out.out
12345678
12345678
12345678
260846532
260846532
260846532

但是,如果我出于相同的目的使用cat,则无法正常工作:

akiiino$ cat in.txt
12345678
12345678
12345678

akiiino$ cat in.txt | ./out.out
260846532
0
0

这种奇怪行为的背后原因是什么,它是否可以解决?我一直认为cating文件与将它们输入没什么不同stdin

Serge Ballesta

区别在于,当您手动键入3个数字时,您正在从终端读取数据,而低电平读取则在换行符处终止。让我们看看幕后情况。

  1. 手动输入:

    • 3个孩子已经开始并等待输入
    • 您输入一个数字和一个新行
    • 基础read呼叫被换行符终止,因为您从终端读取
    • 第一个孩子(被读取的孩子)对其scanf调用进行解码,并对输入进行处理

    好吧,我们对另外两个孩子进行相同的迭代

  2. 从文件或管道读取

    • 3个孩子已经开始并等待输入
    • 3个数字和换行符立即可用
    • read第一个孩子的基础读取并消耗了stdio缓冲区中的所有输入
    • 第一个孩子(被读取的孩子)对其scanf调用进行解码(输入的第一部分)并进行处理

    但是现在其他两个孩子正在从位于文件末尾的文件/管道读取。他们的scanf返回0,但是您无法控制它,并且他们将初始未确定的值输入num

您可以通过sleep(10)在循环前添加a ,在第一个孩子开始阅读之前用手输入3个数字来启动程序,来控制这不是比赛条件的问题由于低级读取将以换行符终止(特殊tty情况),即使在第一次读取之前有3行可用,您仍然会获得与第一种情况相同的输出。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章