2

我是 ANSI C 的初学者,我有一个问题,这可能是个愚蠢的问题,我很抱歉。

#include<stdio.h>
    main()
    {
          int age;
          printf("Hello World!\n");
          printf("Please enter your age: ");
          scanf("%d", &age);
          printf("You entered %d\n", age);
          fflush(stdin);
          getchar();
    }

这是我学习scanf函数的第二个程序。我的问题是:我知道printfscanffflushstdingetchar是在stdio.h中定义的,但只有当我使用fflush(stdin)时我必须输入#include< stdio.h >,但是当使用任何其他方法时我可以删除该行#include。

4

2 回答 2

9

当您调用在该标头中声明的任何函数时,您必须拥有。#include <stdio.h>

好吧,这并不完全正确。在 1989/1990 版本的语言标准中,调用可以创建函数的隐式声明。如果这恰好与正确的声明相匹配,您就可以侥幸逃脱;。否则你的程序的行为是不确定的——这意味着你仍然可能逃脱它,或者没有,但是编译器不需要警告你。由于printf需要可变数量的参数,因此您必须有一个可见的声明以避免未定义的行为 - 获得可见声明的方法是#include <stdio.h>.

(您也可以自己声明该函数,但这很容易出错,而且没有充分的理由这样做。)

在 C99 及更高版本中,没有隐式声明。

main()应该是int main(void)

fflush(stdin)具有未定义的行为。如果要丢弃scanf()调用后输入的字符,可以读取并丢弃它们。

于 2012-07-22T22:54:58.603 回答
2

您可能需要该头文件,因此stdin将被定义。如果你关闭了编译器警告,编译器不会让你知道未定义的函数。(如果它们真的是未定义的,你稍后会得到一个链接器错误)。stdin是类型的变量FILE *,而不是函数。

请不要打电话fflush(stdin)。它具有未定义的行为。如果您需要清除输入缓冲区,请使用另一种方法。执行此操作的标准方法是尝试读取数据,直到下一行结束:

int flush_line(FILE *file)
{
    int ch;
    do {
        ch = fgetc(file);
    } while (ch != '\n' && ch != EOF);
    if (ch == EOF && ferror(file)) {
        return -1;
    }
    return 0;
}

然后你会打电话给flush_line(stdin).

如果不考虑可移植性(注意这不适用于 Windows),您可以暂时使文件描述符为非阻塞并从中读取所有输入:

int flush_in(FILE *file)
{
    int ch;
    int flags;
    int fd;

    fd = fileno(file);
    flags = fcntl(fd, F_GETFL, 0);
    if (flags < 0) {
        return -1;
    }
    if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
        return -1;
    }
    do {
        ch = fgetc(file);
    } while (ch != EOF);
    clearerr(file);
    if (fcntl(fd, F_SETFL, flags)) {
        return -1;
    }
    return 0;
}

然后你会打电话给flush_in(stdin).

于 2012-07-22T22:46:49.403 回答