22

I am learning C and I'm using "getchar()" to stop the command windows so I can see the exercises am doing but it just doesn't work. heres a sample:

#include <stdio.h>

int main()
{
    int value;
    printf("1. option 1.\n2. option 2.\n3. option 3.\n4. Exit\n\nMake an option: ");
    scanf("%d", &value);
    switch (value)
    {
        case 1:
            printf("you selected the option 1.");
            break;
        case 2:
            printf("you selected the option 2.");
            break;
        case 3:
            printf("you selected the option 3.");
            break;
        case 4:
            printf("goodbye");
            break;
        default:
            printf("thats not an option");
            break;
    }
    getchar();
    return 0;
}

this is the output:

  1. option 1.
  2. option 2.
  3. option 3.
  4. Exit.

Make an option: 1

you selected the option 1.

Process returned 0 (0x0) execution time : 3.453 s

Press any key to continue.

Why doesn't it wait for the input of "getchar()"?

DigitalRoss
  • 143,651
  • 25
  • 248
  • 329

10 Answers10

24

Your scanf only ate the number but not the trailing newline. Putting a newline or white space after the %d will then give you the opposite problem, reading too far.

This is why people don't like scanf.

I would suggest reading an actual line (use fgets(3)) and then using sscanf() to scan the string.

DigitalRoss
  • 143,651
  • 25
  • 248
  • 329
8

First of all, do not use fflush() to clear an input stream; the behavior is undefined:

7.19.5.2.2 If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.

The problem is that the trailing newline is not being consumed by the "%d" conversion specifier, so it's being picked up immediately by the getchar(). There's no one best way to deal with this, but generally the approach is to read the whole line as text (using either fgets() or scanf() with a sized "%s" conversion specifier), which will consume the newline, then convert to the target data type using sscanf() or strtol() or strtod().

John Bode
  • 119,563
  • 19
  • 122
  • 198
3

Can getchar be getting your carriage return that you enter after the 1?

John Lockwood
  • 3,787
  • 29
  • 27
  • Yes, getchar() is getting the newline that terminates the input, and therefore it does not wait long since the data is already in its buffers. – Jonathan Leffler Sep 08 '09 at 01:38
  • Heck if that was wrong. I'm liking the fflush answer and trying it out. – John Lockwood Sep 08 '09 at 01:40
  • 2
    But it's undefined behavior, potentially nonportable, and particularly not recommended for a homework-style learning experience. Follow the published and standardized API! :-) – DigitalRoss Sep 08 '09 at 02:14
2

The getchar() is reading the \n from the keyboard in scanf - see here for more info

Preet Sangha
  • 64,563
  • 18
  • 145
  • 216
2

I think you input a enter after inputting "1". It will be accepted by the getchar().So you can solve the problem simply by add an additional getchar() after the original one(just before the return 0;).

** I tested this and it worked.

Steephen
  • 14,645
  • 7
  • 40
  • 47
zxeoc
  • 76
  • 1
2

As mentioned already scanf leaves \n behind after reading user input.

Soultion: add getchar() straight after scanf.

That compensates scanf deficiency.

i.e.

int value; 
printf("1. option 1.\n2. option 2.\n3. option 3.\n4. Exit\n\nMake an option: "); 
scanf("%d", &value);
getchar();
switch (value) 
Alex
  • 21
  • 1
2

you are getting a carriage return, the way i would get around it, define a char and just have it scan the carriage return,

char ch; (before your getch() enter the following) scanf("%c",&ch); getchar();

should work this way, not the most efficient way to do this but works for me.

0

while reading other answers it just came to me that you can use scanf("%d\n",&n); instead of scanf("%d",&n); to remove new line from buffer. I haven't checked this out though.

Hope it works :D

  • I think this won't work for recursive functions but should work fine for loops. "You can't please everyone" – Jayanta Banik Oct 18 '18 at 20:10
  • 1
    This won't work as expected. Because of the `\n` in the format string, `scanf` won't return until you enter a non-whitespace character *after* entering any digits. – dbush Oct 18 '18 at 20:27
-2
#include <stdio.h> 
#include<conio.h>
void main() 
{ 
    int value; 
    printf("1. option 1.\n2. option 2.\n3. option 3.\n4. Exit\n\nMake an option: "); 
    scanf("%d", &value); 
    switch (value) 
    { 
        case 1: 
            printf("you selected the option 1."); 
            break; 
        case 2: 
            printf("you selected the option 2."); 
            break; 
        case 3: 
            printf("you selected the option 3."); 
            break; 
        case 4: 
            printf("goodbye"); 
            break; 
        default: 
            printf("thats not an option"); 
            break; 
    } 
    getch(); 
} 
sth
  • 222,467
  • 53
  • 283
  • 367
don
  • 1
-10

in order for your program to work, you should "flush" your input stream before calling getchar() with a call to fflush(stdin). What this does is, when you type in you keyboard a number and then the return key, the input buffer gets both characters, for example '1' and '\n', and your call to scanf gets only '1' so the '\n' remains in the input buffer. When you call getchar, you are "gettin" that remaining '\n'. Flushing the input discards all the buffer.

nairdaen
  • 1,037
  • 2
  • 11
  • 19
  • 3
    `fflush(stdin)` is _undefined behavior_. Don't do it. – Andrew Keeton Sep 08 '09 at 02:00
  • then how i should do it? am really new to this, am coming from python as my first programming language so everything about memory management is Chinese to me.. –  Sep 08 '09 at 02:07
  • 1
    wow .. I didn't know .. just made some research and found this explanation http://www.gidnetwork.com/b-57.html – nairdaen Sep 08 '09 at 02:08
  • 2
    See my answer or the accepted answer in http://stackoverflow.com/questions/1384073/problem-with-flushing-input-stream-c/1384089. It comes down to a) using `fgets` to read the entire line then parse it using `sscanf` or b) putting in a second `getchar` to "eat" the newline. – Andrew Keeton Sep 08 '09 at 02:09
  • 3
    Sorry to be harsh about `fflush(stdin)`, but it's one of those things that really seems like it should work until it causes a nasty bug that you can't track down. – Andrew Keeton Sep 08 '09 at 02:12
  • I've deleted my answer since this is such a **BAD** idea :) – warren Sep 08 '09 at 12:01