检查输入流在 C 中是否为空

Check if the input stream is empty in C

提问人:Haskell-newb 提问时间:3/20/2018 最后编辑:Haskell-newb 更新时间:3/20/2018 访问量:1589

问:

我正在学习 C 语言,我的程序有问题。

所以,我有这个程序,叫做这个程序,应该允许我使用或使用输入流来读取参数。TESTargv[]$ TEST < argsTest.json

argsTest.json :
{
"a" = 2,
"b" = 3
}

为了简化我的问题,我将使用这个简单的程序:

Struct {
    int a;
    int b;
} number;

int main(int argc, char **argv) {
    json_t * root;
    struct number numbers;
    int c = 0, i = 0 , result;
    char str[1024]; // I'm not using malloc just to simplify my question
    // default values
    numbers.a = 0;
    number.b = 0;

    if (argc == 1 && !feof(stdin)) {
        while((c = fgetc(stdin)) != EOF) {
            str[i]=c;
            ++i;
        }
        str[i] = '\0';

        .... // code that use jansson library to extract value

        /** let's suppose we have extracted the two value int json_a
          * and int json_b.
          */

        numbers.a = json_a;
        numbers.b = json_b;

    } else if (argc == 3) {
        scanf("%d", numbers.a);
        scanf("%d", numbers.b);
    }

    result = numbers.a + number.b;
    printf("%d\n", result);

    return 0;
}

所以,我正在尝试实现三种行为:

  1. $ TEST它应该显示(我们使用了默认值)。0
  2. $ TEST < argsTest.json显示。5
  3. $ TEST 4 3显示。7

我的问题是,如果语句,实际上和有相同的语句,所以 运行它时 bug 因为他输入了第一个条件。if (argc == 1 && !feof(stdin))$ TEST$ TEST < argsTest.jsonargc == 1$ TEST

我想要一个 if 语句来检查输入流是否为空并有参数,这样我就可以在不进入 if 语句的情况下实现第一种情况。0

谢谢。

C 壳体 feof

评论

1赞 Tim 3/20/2018
如果 stdin 缓冲区为空,则可能重复
1赞 that other guy 3/20/2018
运行时,stdin 不为空。相反,stdin 是您在终端上输入的任何内容。您必须按 Ctrl+D 才能将终端输入视为空。我强烈建议你重新考虑你的界面,并与系统合作,而不是反对它。规范行为更易于实现和使用。TEST
0赞 Haskell-newb 3/20/2018
@Tim 不,它不一样,它非常相似我同意,但在他的情况下,他从缓冲区中读取了它,所以他不得不用“Ctrl+d”发送它,在我的情况下,我想自动执行它而不进入 if 语句。即使我必须更改 if 语句。EOF
0赞 Haskell-newb 3/20/2018
@thatotherguy 如果可能的话,你能给我举个小例子吗?就像我说的,我对 C prog.language 很陌生。
0赞 user253751 3/20/2018
@Haskell-newb 计算机如何知道你是否要输入某些内容,或者你是否要输入某些内容但你还没有输入?

答:

2赞 user3386109 3/20/2018 #1

总体思路是

  • 首先检查是否应该使用argcargv
  • 检查终端是否具有交互性
    • 如果是,则只需打印 0
    • 如果它不是交互式的,那么您可以从stdin

问题在于,没有可移植的方法来检查是否是交互式的。但是,在 POSIX 系统上,您可以使用该功能,如本问题所述stdinisatty

因此,假设您使用的是 POSIX 系统,代码如下所示:

int main(int argc, char *argv[])
{
    struct number numbers;

    if (argc == 3)
    {
        if (sscanf(argv[1], "%d", &numbers.a) == 1 && sscanf(argv[2], "%d", &numbers.b) == 1)
            printf("From argv the answer is %d\n", numbers.a + numbers.b);
        else
            printf("Bad strings in argv\n");
    }
    else if (isatty(STDIN_FILENO))
    {
        printf("Nothing in argv or on stdin, so the answer is 0\n");
    }
    else
    {
        if (scanf("%d%d", &numbers.a, &numbers.b) == 2)
            printf("From stdin the answer is %d\n", numbers.a + numbers.b);
        else
            printf("Found junk on stdin\n");
    }
}

评论

1赞 Haskell-newb 3/20/2018
感谢您提供这些详细信息,我非常感激,幸运的是我在 POSIX 系统上。