Thread: Leaving charscters in input buffer

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    1

    Leaving charscters in input buffer

    I'm making my first steps in ANSI C and I have run to a problem .
    The code below should read an integer and then a string, but it doesn't. It reads the integer and then exits. I found out that scanf leaves a '\n' character in the input buffer and then fgets reads the '\n' and exits without asking for the string.

    Code:
    #include <stdio.h>
    
    int main()
    {
        
    int x;
    char st[5];
    
    printf("Enter an integer: ");
    scanf("%d", &x);
    printf("Enter a line of text: ");
    fgets(st, 5, stdin);
    
    }

    I tried to solve the problem with the code below. Mainly the problem was solved
    but still there is a draw back. After entering the 1st string the ENTER key has to be pressed
    twice in order to proceed to the second input.
    If there are any ideas on how to solve this it will be much appreciated.

    Code:
    #include <stdio.h>
    
    void dump_line( FILE * fp )
    {
      int ch;
    
      while( getchar() != '\n' )
        /* null body */;
    }
    
    int main()
    {
        
    int x;
    char st[5];
    
    printf("Enter an integer: ");
    scanf("%d", &x);
    dump_line(stdin);
    printf("Enter a line of text: ");
    fgets(st, 5, stdin);
    dump_line(stdin);
    printf("Enter a line of text: ");
    fgets(st, 5, stdin);
    
    }

  2. #2
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    You are probably not aware of sscanf(). But that is what you want (Force: Mind Trick)
    Code:
    #include <stdio.h>
    
    int main()
    {    
    int x;
    char st[1024];
    printf("Enter an integer: ");
    fgets(st, 1024, stdin);
    sscanf(st, "&#37;d", &x);
    }
    or better
    Code:
    #include <stdio.h>
    
    int main()
    {    
    int x;
    char st[1024];
    printf("Enter an integer: ");
    fgets(st, 1024, stdin);
    x = atoi(st);
    }
    since atoi is a bit more "flexible" (will ignore leading whitespaces for example).
    I used 1024 just as a big enough buffer. It is only 1kB so you wouldn't really care. No need to skip lines like this. atoi (or sscanf) will read the buffer that contains a \0 and \n from fgets() but will ignore them.

    There are some functions to dumb a line. One I thing is fflush(stdin). Others are some functions in the non-standard <conio.h> which will read a character without wanting an ENTER. Clearly fgets() and atoi() are better

    edit: The logic is get the string with fgets() and then do whatever you want with the string, without worrying about remaining \n, buffer overlows and whatever.
    Just to mention also the strtoX set of functions that can convert a string to an int, double, float, long etc etc in whatever base you want.
    Last edited by C_ntua; 11-24-2008 at 01:31 PM.

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by pavlosgr View Post
    I'm making my first steps in ANSI C and I have run to a problem .
    The code below should read an integer and then a string, but it doesn't. It reads the integer and then exits. I found out that scanf leaves a '\n' character in the input buffer and then fgets reads the '\n' and exits without asking for the string.

    Code:
    #include <stdio.h>
    
    int main()
    {
        
    int x;
    char st[5];
    
    printf("Enter an integer: ");
    scanf("%d", &x);
    printf("Enter a line of text: ");
    fgets(st, 5, stdin);
    
    }

    I tried to solve the problem with the code below. Mainly the problem was solved
    but still there is a draw back. After entering the 1st string the ENTER key has to be pressed
    twice in order to proceed to the second input.
    If there are any ideas on how to solve this it will be much appreciated.

    Code:
    #include <stdio.h>
    
    void dump_line( FILE * fp )
    {
      int ch;
    
      while( getchar() != '\n' )
        /* null body */;
    }
    
    int main()
    {
        
    int x;
    char st[5];
    
    printf("Enter an integer: ");
    scanf("%d", &x);
    dump_line(stdin);
    printf("Enter a line of text: ");
    fgets(st, 5, stdin);
    dump_line(stdin);
    printf("Enter a line of text: ");
    fgets(st, 5, stdin);
    
    }
    You do NOT want to clean up the input buffer after fgets(), as that will read the newline. So when you get to the getchar() in your "dump" function, you need to hit enter again before it receives any input.

    As c_ntua says, you can use functions to read the a string and then convert to an integer (or floating point).

    I personally prefer to use strtol() rather than atoi(), as atoi is sensitive to overflow and does not tell you if the WHOLE string got accepted or only parts (e.g. atoi() will accept 1123aba and return 1123 - so does strtol(), but you can, if you want to check that the WHOLE number got accepted, you can find out that there was "aba" left in the string with strtol - that information is lost with atoi).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    or drop the second call to dump_line().

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by itCbitC View Post
    or drop the second call to dump_line().
    Is that not about the same as:
    Quote Originally Posted by MatsP
    You do NOT want to clean up the input buffer after fgets(), as that will read the newline. So when you get to the getchar() in your "dump" function, you need to hit enter again before it receives any input.
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Yes it is matsp!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need some help with C program writing
    By The_PC_Gamer in forum C Programming
    Replies: 9
    Last Post: 02-12-2008, 09:12 PM
  2. Clearing c++ input buffer
    By mramazing in forum C++ Programming
    Replies: 4
    Last Post: 11-08-2007, 11:05 AM
  3. Can't seem to come to conclusion : cin.ignore()
    By SkyHi in forum C++ Programming
    Replies: 8
    Last Post: 05-13-2005, 08:57 PM
  4. How can you tell if the input buffer is empty?
    By Punkture in forum C Programming
    Replies: 1
    Last Post: 06-04-2003, 05:10 PM
  5. getline problem
    By Unregistered in forum C++ Programming
    Replies: 4
    Last Post: 10-06-2001, 09:28 AM