2

I am a beginner in ANSI C, and I have a question, it may be silly question and I am sorry for it.

#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();
    }

It is my second program to learn scanf function. My question is : I know that printf, scanf, fflush, stdin, and getchar are defined in stdio.h but only when I use fflush(stdin) I must put #include<stdio.h>, but when use any other method I can remove that line #include.

kyle k
  • 5,134
  • 10
  • 31
  • 45
Mahmoud Emam
  • 1,499
  • 4
  • 20
  • 37
  • Are you already including any other header files? – Jonathon Reinhart Jul 22 '12 at 22:45
  • No, this is code. I can't understand what's the difference between both – Mahmoud Emam Jul 22 '12 at 22:47
  • It's worth noting that `fflush(stdin)` though works on some implementations, it's still undefined behavior. According to the standard, `fflush` only works with output/update streams. – Yu Hao Aug 31 '13 at 07:46
  • Note that on some systems (notably Windows with the Microsoft libraries), `fflush(stdin)` is defined behaviour. On many systems, and according to the C and POSIX standards, it is undefined behaviour. See also [Using `fflush(stdin)`](http://stackoverflow.com/questions/2979209/using-fflushstdin). – Jonathan Leffler Jan 25 '15 at 15:49

2 Answers2

9

You must have #include <stdio.h> when you call any function declared in that header.

Ok, that's not quite true. In the 1989/1990 version of the language standard, a call can create an implicit declaration of a function. If that happens to match the correct declaration, you can get away with it;. Otherwise your program's behavior is undefined -- which means you still might get away with it, or not, but the compiler isn't required to warn you about it. Since printf takes a variable number of arguments, you must have a visible declaration to avoid undefined behavior -- and the way to get a visible declaration is #include <stdio.h>.

(You can also declare the function yourself, but that's error-prone, and there's no good reason to do that.)

In C99 and later, there are no implicit declarations.

main() should be int main(void).

fflush(stdin) has undefined behavior. If you want to discard characters entered after the scanf() call, you can read and discard them.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • Note that even C89/90 required a declaration of _any_ variadic function such as `printf()` before it was used. Granted, you could (still can) write `extern int printf(const char *fmt, ...);` before using it and that would meet the goal. However, including the header is far more sensible. – Jonathan Leffler Jan 25 '15 at 15:47
  • @JonathanLeffler: But it didn't enforce that requirement. As I said, calling `printf` without a visible declaration in C90 has undefined behavior -- but it's very likely to "work". – Keith Thompson Jan 25 '15 at 16:03
  • Yes, it was undefined behaviour. I should perhaps have stated that I meant "the C89/90 standard" rather than "C89/90 implementations", but the statement in your answer that I was addressing already had that qualification in place. It is only a minor footnote, not a major issue. – Jonathan Leffler Jan 25 '15 at 16:07
2

You probably need that header file so stdin will be defined. If you have compiler warnings turned off, the compiler will not let you know about undefined functions. (If they really are undefined, you'll get a linker error later on). stdin is a variable of type FILE *, not a function.

Please do not call fflush(stdin). It has undefined behaviour. If you need to clear the input buffer, use another method. The standard way to do this is to attempt to read data until the end of the next line:

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;
}

And then you would call flush_line(stdin).

If portability is not a concern (note that this will not work with Windows), you could temporarily make the file descriptor non-blocking and read all input from it:

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;
}

And then you would call flush_in(stdin).

craig65535
  • 3,439
  • 1
  • 23
  • 49
  • 1
    And let the battle begin: http://stackoverflow.com/questions/8798063/error-receiving-inputs/8798071#8798071 – Jonathon Reinhart Jul 22 '12 at 22:48
  • @JonathonReinhart it's not a battle, `fflush(stdin)` is not only non-portable, but also ill-equipped to behave correctly on any non-line-buffered input. – Dave Jul 22 '12 at 23:29
  • Haha, I love how posting that comment earned me -2 on that answer. Foolish of me, huh. – Jonathon Reinhart Jul 22 '12 at 23:51
  • Make that -3. `fflush(stdin)` does not do what you think it does, and an accepted answer that's **that** wrong and which the author does not fix should have a high negative score to alert readers that it's wrong. – R.. GitHub STOP HELPING ICE Jul 23 '12 at 15:22