【问题标题】:stdout/stdin and Parameters标准输出/标准输入和参数
【发布时间】:2016-12-01 18:20:09
【问题描述】:

我的程序有点问题,不知道如何解决。只要我不包含getopt(不带参数),我的程序就可以正常工作。

我写了2个简单的程序Server&Client

服务器将数字写入stdout,客户端应使用stdin 读取它们。

此外,程序应该能够使用参数(参数)调用。

例如,程序的调用如下所示:

Terminal: ./Server -f72 | ./Client -r22

如果我运行程序,那么它只会打印带有参数“22”和“Waiting for Server”的“Her is r”,但它应该打印来自服务器的数字

我找不到错误。我将衷心感谢您的帮助。提前感谢所有阅读本文的人。

服务器:

int main(int argc , char *argv[])
{
    int i;
    FILE *ziel;
    ziel=stdout;

    int option;
    char buf[50];

    while ((option = getopt(argc, argv,"f:tr:d:j")) != -1)
    {
        switch (option)
        {
            case 'f' :
                strcpy(buf,optarg);
                break;
            case 't' :              
                break;
            case 'r' :
                strcpy(buf,optarg);
                break;
            default:
                //printf("1ERROR");
                exit(EXIT_FAILURE);
        }
    }

    for(i=1;i>0;i++)
    {
        fprintf(ziel,"%d\n",i);
        sleep(1);
    }
    return 0;
}

客户:

int main(int argc , char *argv[])
{
    FILE* cl;
    cl=stdin;
    int i;
    int zahl[10];
    int option;
    char buf[50];

    while ((option = getopt(argc, argv,"f:tr:")) != -1)
    {
        switch (option)
        {
            case 'f' :
                puts("Here is f");
                strcpy(buf,optarg);
                puts(buf);
                break;
            case 't' :
                puts("Here is t");
                break;
            case 'r' :
                puts("Here is r");
                strcpy(buf,optarg);
                puts(buf);
                break;
            default:
                printf("ERROR");
                exit(EXIT_FAILURE);
        }
    }

    puts("Waiting for Server");
    for(i=0;i<10;i++)
    {
        fscanf(cl,"%d",&zahl[i]);
        printf("Received %d\n ",zahl[i]);

    }

    return 0;
}

【问题讨论】:

  • 并运行 ./Server -f72 会发出正确的数字吗?
  • 是的。我也在另一个程序中使用它,其中参数很重要,而通过管道传递它的程序只打印参数字符串。
  • 所以上面的这个例子有效吗?在这种情况下,它不是minimal reproducible example。您确定您的其他程序不使用stderr 而不是stdout?您必须发布真实案例和控制台输出。你真的确定getopt是罪魁祸首吗?因为我严重怀疑它。
  • 好吧,我昨天已经做到了。该示例不起作用。我确定我使用 stdout 我定义了一个指向它的指针。不信我可以发一些终端截图*.com/questions/40874117/…
  • 我相信你有问题,你不会发布问题只是为了惹恼我们:) 我对复制器和原因有疑问,仅此而已。

标签: c pipe stdout stdin getopt


【解决方案1】:

您示例中的问题与getopt 无关。这是关于输出缓冲

如果等待的时间足够长,应该会一口气出现一堆数字。

我通过修改服务器程序使其工作

  • 删除sleep(1)
  • 或者在fprintf之后使用fflush(stdout);

  • 在终端中打印时,遇到换行符时会刷新输出,这就解释了它的工作原理。

  • 在重定向输出中打印时,会发生缓冲。您必须显式刷新缓冲区(C 库可能会决定刷新,但这不是这里发生的事情)

您无法从您的客户那里控制它。在您的情况下,即使将服务器传送到 more 也不起作用。

另请阅读:Does reading from stdin flush stdout?

注意:你可以欺骗你的服务器程序,让它相信它写在 tty 中,这有点 hacky 但可以工作:

Pretend to be a tty in bash for any command

(我目前没有 Windows 解决方案)

【讨论】:

  • 非常感谢!!!我没想到。 sleep 只是模拟了我需要计算我要发送的值的时间,但它现在可以工作了