Thread: Why does program jump over first data input line?

  1. #1
    zach
    Guest

    Why does program jump over first data input line?

    Code:
    #include <stdio.h>
    #include<string.h>
    #include<windows.h>
    
    void menu (void);
    void locate(short x, short y);
    //void removeScrollbars(void);
    void enterBill(void);
    
    struct A
        {
            char bill[6];
            char date[10];
            char descr[36];
            char euros[9];
            char code[6];
        };
    
    int main(void)
    {
        //removeScrollbars();
        menu();
    
    }
    
    void menu(void)
    {
        system("@cls||clear");
        char s;
        locate(5,5); printf("1 = Enter a bill");
        locate(5,6); printf("2 = Retrieve a bill");
        locate(5,7); printf("3 = Correct a bill");
        locate(5,8); printf("4 = Enter a description");
        locate(5,9); printf("5 = Change a description");
        locate(5,11); printf("Make a selection: ");
        s = getchar();
        if (s == '1') enterBill(); else exit(0);
    }
    
    void enterBill(void)
    {
        system("@cls||clear");
        struct A B;
    
        strcpy(B.bill,"");
        strcpy(B.date,"");
        strcpy(B.descr,"");
        strcpy(B.euros,"");
        strcpy(B.code,"");
    
        // This entry line is being passed over
    
        char *p;
        locate(5,5);printf("Bill numer");locate(30,5);printf(": ");
        fgets(B.bill, sizeof(B.bill),stdin);    
        if( (p = strchr(B.bill,'\n')) != NULL ) *p = '\0';
            
        locate(5,6);printf("Enter date");locate(30,6); printf(": ");
        fgets(B.date, sizeof(B.date),stdin);                         
        if( (p = strchr(B.date,'\n')) != NULL ) *p = '\0';
    
        locate(5,7);printf("Amount");locate(30,7);printf(": ");
        fgets(B.euros, sizeof(B.euros),stdin);                
        if ( (p = strchr(B.euros,'\n')) != NULL ) *p = '\0';
    
        locate(5,8);printf("Code");locate(30,8);printf(": ");
        fgets(B.code, sizeof(B.code),stdin);
        if ( (p = strchr(B.code,'\n')) != NULL ) *p = '\0';
    
    
        FILE *C;
        C = fopen("data2","ab");
        fwrite(&B,sizeof(struct A),1,C);
        fclose(C);            
    
    }
    
    void locate(short x, short y) 
    {
        COORD pos = {x, y};
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
    }
    Above is a test program to find out why the program jumps over the first entry line when you select 1 in the menu. I am showing a lot of code hoping my question will be clear. Please help. Many thanks, Zach.

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Probably because you left a new line character in the input buffer inside the menu() function.

  3. #3
    zach
    Guest
    Quote Originally Posted by jimblumberg View Post
    Probably because you left a new line character in the input buffer inside the menu() function.
    Yes I assumed there was something left in a buffer; the question of course is where is what getting stuck, and how can I get rid of it. I have been trying everything I could think of for many hours, but in vain. I have given a lot of code, so one of you clever guys could put your finger on it )

  4. #4
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Well the problem occurs because of the getchar() on line 36, and the problem is "seen" on line 55. The problem is that getchar() leaves the newline character in the input buffer, check the boards FAQ there are a couple of entries about this "problem"

    How do I avoid a "dangling" newline when reading single character user input?

    and

    Flush the input buffer

  5. #5
    zach
    Guest
    Your first quote is about scanf, which I was previously told to avoid because of its hicks and tricks.

    It cannot surely be true that you have to add lines of code to compense for the C language dysfunctioning!!

  6. #6
    zach
    Guest
    Quote Originally Posted by jimblumberg View Post
    Well the problem occurs because of the getchar() on line 36, and the problem is "seen" on line 55. The problem is that getchar() leaves the newline character in the input buffer, check the boards FAQ there are a couple of entries about this "problem"

    How do I avoid a "dangling" newline when reading single character user input?

    and

    Flush the input buffer
    The first quote uses scanf, which I don't in my test code because I was told not to because of its hicks and tricks.

    The second code

    Code:
    #include <stdio.h> 
    
    int main(void)
    {
     // int   ch;
     // char  buf[BUFSIZ];
       
     // while ((ch = getchar()) != '\n');
     
     printf ("Enter some text: ");
      
      if (fgets(buf, sizeof(buf), stdin))
      {
        printf ("You entered: %s", buf);
      }
      
      return 0;
    }
    The last three lines only make sense to my C-rooky brain.

  7. #7
    Registered User
    Join Date
    Dec 2017
    Posts
    1,628
    total moron
    A little inaccuracy saves tons of explanation. - H.H. Munro

  8. #8
    zach
    Guest
    So, Jim, C is a language of which you cannot simply use the data input functions, because you will end up in a hell of a mess? Zach. K

  9. #9
    zach
    Guest
    Quote Originally Posted by john.c View Post
    total moron
    John, in response to calling me a "total moron": are you using this forum to wank your ego?
    Last edited by zach; 08-30-2019 at 02:44 PM.

  10. #10
    zach
    Guest
    Jim, first of all as I was told, don't use scanf, secondly, the golden code line seems to be:

    Code:
        //s = getchar();
        while ( getchar() != '\n' );
        // use s
    Well if that suffices, that is not so bad then.
    Although I think a mature language shouldn't need such plasters.
    Thank you for your help! Zach k.

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by zach
    Your first quote is about scanf, which I was previously told to avoid because of its hicks and tricks.
    The problem with scanf is basically the same problem you have with using getchar to read a char: it leaves the newline from entering the input in the input buffer, which doesn't play well with fgets and other line-based input functions. If you want to avoid scanf because of this, then avoid getchar as well: always use fgets or other line-based input functions to read the entire line of input, then parse the line for what you want, possibly with sscanf (but other functions are available too, e.g., strtol, or if you just want a char, you can easily manually parse the line for that char).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    zach
    Guest
    Quote Originally Posted by laserlight View Post
    The problem with scanf is basically the same problem you have with using getchar to read a char: it leaves the newline from entering the input in the input buffer, which doesn't play well with fgets and other line-based input functions. If you want to avoid scanf because of this, then avoid getchar as well: always use fgets or other line-based input functions to read the entire line of input, then parse the line for what you want, possibly with sscanf (but other functions are available too, e.g., strtol, or if you just want a char, you can easily manually parse the line for that char).
    Thank you! I will have to chew over what you say. I still have much to learn. I am making a reference manual for myself as I go along and learn from my needs , mistakes and responses like yours. Zach.

  13. #13
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Quote Originally Posted by zach View Post
    Although I think a mature language shouldn't need such plasters.
    Don't forget that C isn't a program language designed to write programs on Windows - The language predates that.

  14. #14
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,110
    Quote Originally Posted by Click_here View Post
    Don't forget that C isn't a program language designed to write programs on Windows - The language predates that.
    The C Programming language was originally "designed" to create a usable version of UNIX, back in 1969/70.

    Once the language was standardized by ANSI through the C89 Standard, and by the ISO, in C90, C99, C11, C17, and future Standards, it is "designed" to be used on ALL O/S's. It is the most universal programming language of all time, BECAUSE of these Standards!

    There are quirks in all programming languages. It is up to the programmer to understand these quirks, and write code that can properly deal with these quirks.

    The issues with getchar(), scanf() and others, are not limited to one or two O/S's! They work the same on ALL O/S / Standards complaint compiler combinations.

    Also, resorting to (Windows based) conio.h functions as a crutch, is NOT the answer!

  15. #15
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,110
    Quote Originally Posted by zach View Post
    Jim, first of all as I was told, don't use scanf, secondly, the golden code line seems to be:

    Code:
        //s = getchar();
        while ( getchar() != '\n' );
        // use s
    Well if that suffices, that is not so bad then.
    Although I think a mature language shouldn't need such plasters.
    Thank you for your help! Zach k.
    The better version of the code is:
    Code:
       int ch = 0;
       while ((ch = getchar()) != '\n' && ch != EOF);
    Simple enough to create a function to call in multiple places. This will work if the input is from the keyboard, from a file, or when using redirection from a file on the command line.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. program hangs when larger input data
    By 花颂 in forum C Programming
    Replies: 1
    Last Post: 04-03-2013, 09:55 PM
  2. Replies: 2
    Last Post: 03-31-2011, 04:50 PM
  3. reading line by line - input function
    By Lindira-123 in forum C Programming
    Replies: 11
    Last Post: 02-06-2011, 03:34 PM
  4. Line of data input method
    By larry_2k4 in forum C Programming
    Replies: 2
    Last Post: 04-28-2009, 11:34 PM
  5. Reading Input from a file, line-by-line
    By Acolyte in forum C Programming
    Replies: 8
    Last Post: 09-30-2007, 01:03 PM

Tags for this Thread