Thread: Why do I need getchar(); in this example?

  1. #1
    Registered User
    Join Date
    May 2007
    Posts
    5

    Question Why do I need getchar(); in this example?

    Hi there, Folks. I've been going through Bruce Eckles's "Thinking in C" flash-based tutorial.

    It's a little annoying as he uses unexplained commands in his answers, which means it's almost impossible to complete the exercise if you're not already familiar with C!

    Anyhow.. I finally figured out how the following works, but I still don't understand why I need a getchar();...

    Code:
        for (n = 0; n < MAXEMPS; ++n) {
            printf("Enter last: "); fflush(stdout);
            gets(emps[n].last);
            if (strlen(emps[n].last) == 0)
                break;
            printf("Enter first: "); fflush(stdout);
            gets(emps[n].first);
            printf("Enter title: "); fflush(stdout);
            gets(emps[n].title);
            printf("Enter salary: "); fflush(stdout);
            scanf("%d", &emps[n].salary);
            getchar();  /* eat newline */
        }
    I'm reading in data from the keyboard to fill in an Employee Struct (last name, first name, title, and salary). When the user enters a blank line (only \n) then it is supposed to stop (thus the if break test).

    But I don't understand why I need the getchar(); at the end there. Where is that EXTRA \n coming from? Is it returned form scanf?

    Thanks in advanced. I just want to understand what's going on in the code.

    Cheers,
    Jeffrey

  2. #2
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Let's say you want to read a number from the user, and you use scanf() to do it. Let's say the user types in "45" at the command line. The input buffer will look like this:

    Code:
    '4', '5', '\n'
    When scanf() completes, it'll read the '4', and '5', but it'll stop at the '\n' char, which was put in the buffer when the user hit enter. So after scanf() executes, the buffer will look like this:

    Code:
    '\n'
    So to get rid of that newline char, you need to read it off. Bruce uses getchar() in that example, apparently, to do this.

    FYI, don't use gets() to read a string. Besides opening up your program to being taken control of by a malicious user, you run the risk of your program not working properly if the size of the buffer is less than the size of the string read into your buffer. As an alternative, use fgets().

  3. #3
    Registered User
    Join Date
    May 2007
    Posts
    5
    Thanks, MacGyver.

    That makes sense. I wasn't thinking of it from a "buffer" perspective... so with the \n still floating around in the input buffer, it will be added first in the next gets??

    I understand about the dangers of gets. Unfortunately Mr. Eckles has not presented any alternatives (I was trying to use sprintf but unsuccessfully).


    Thank you again.

    Jeffrey

  4. #4
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by JDShaffer View Post
    That makes sense. I wasn't thinking of it from a "buffer" perspective... so with the \n still floating around in the input buffer, it will be added first in the next gets??
    Correct. Any other input function will read off the '\n' next.

    While on the subject, input is potentially buffered behind the scenes on multiple levels actually. The buffer from the standard C library is just one layer of it.

    Quote Originally Posted by JDShaffer View Post
    I understand about the dangers of gets. Unfortunately Mr. Eckles has not presented any alternatives (I was trying to use sprintf but unsuccessfully).

    fgets() example:

    Code:
    char buffer[BUFSIZ];
    int iIndex;
    
    ...
    
    fgets(buffer,sizeof(buffer),stdin);
    iIndex = strlen(buffer) - 1;
    if(buffer[iIndex] == '\n')
    {
    	buffer[iIndex] = '\0';
    }
    fgets() requires both the size of the buffer, and the file to read from. In C, there are 3 file objects open by default:

    • stdin
    • stdout
    • stderr


    You use at least one or two of them all the time most likely, but you may not realize it. Functions like printf(), putchar(), and puts() all write to the file stdout. That is what you end up seeing on the terminal display since that is what stdout is mapped to by default. Functions like scanf() and getchar() read from the file stdin. That is usually input coming from the keyboard, and is read at the terminal since that is the default for stdin.

    These files are not true files in the sense of being some place on the hardrive like a text file, but for many purposes they behave the same way as if you're dealing with files. You can think of them as files in how you can interact with them in your programs.

    So anyway, back to fgets().... As mentioned, it requires you to pass the size of the buffer as well as the file that you're reading from. A small difference between gets() and fgets() is that fgets() will include the '\n' when reading the string. gets() will read up to the '\n' but will discard it after reading it so it won't be in your char array. This is why I added the check to get rid of the '\n', because many times you don't usually want it. BTW if no '\n' is included in the char array after you call fgets(), you know you didn't read the entire line.

    It involves slightly more work to use fgets(), but it is much safer and the better way of reading a line from the user.
    Last edited by MacGyver; 05-15-2007 at 01:35 AM.

  5. #5
    Registered User
    Join Date
    May 2007
    Posts
    5
    Wow, thanks for the detailed explanation!

    I did know about the three standard buffers, though I didn't realize, honestly, that things would stay there. I thought they were only used when called, and then emptied!

    As for using fgets, yes that does seem a bit more complicated. Perhaps at the level I'm working at gets is ok (as long as I don't overrun my strings!). But I should definitely keep the fgets in the back of my mind for "proper" programming later on.

    So much to learn and so little time. Ha ha ha.

    Thank you again.
    Jeffrey

  6. #6
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by JDShaffer View Post
    As for using fgets, yes that does seem a bit more complicated. Perhaps at the level I'm working at gets is ok (as long as I don't overrun my strings!). But I should definitely keep the fgets in the back of my mind for "proper" programming later on.
    I would insist you make an attempt at using fgets() instead of gets(). The problem is that you will be used to using it, and bad habbits are hard to break. You really should look into using fgets().

    I've been meaning to write and release a very small library for people like you that are trying to learn, but don't really want to take the time to learn the little details as to how to "properly" read input safely.

    I'm going to have to finish that up and release it soon.

  7. #7
    Registered User
    Join Date
    May 2007
    Posts
    5
    Hello again.

    Thanks for the good suggestion. I would definitely take your suggestion if I were planning on doing a lot of coding in C (this is my second time around with C, the first being many a moon ago). But my goal is to write neural networks in Java... so the Java book I'm planning on using has the reader going through a quick "intro to C" course to get some background on Java.

    Is it worth the trip through C to get to Java? I dunno... but it's nice to go back and actually be able to do SOME things with C. :-)

    Thanks again, and who knows.. perhaps I'll get hooked and wind up doing stuff in C as well as in Java.

    Cheers,
    Jeffrey

    PS -- Is the Kernan and Richtie (sp?) book available online these days? (Programming in C?)

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Is it worth the trip through C to get to Java?
    No, you should start on a book that actually teaches Java properly, or a book that actually teaches C properly.
    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

  9. #9
    Lean Mean Coding Machine KONI's Avatar
    Join Date
    Mar 2007
    Location
    Luxembourg, Europe
    Posts
    444
    Quote Originally Posted by JDShaffer View Post
    Is it worth the trip through C to get to Java?
    Hell no. I could imagine how C++ would maybe help you understand Java a little better but C? It's always good to know how memory management, pointers and all the other things work but Java is so much more high level than C that you can't possible compare the two.

  10. #10
    Its hard... But im here swgh's Avatar
    Join Date
    Apr 2005
    Location
    England
    Posts
    1,688
    C++ books are being written all the time, but C books are getting harder to get hold of ( new and updated ones I mean ) But I use C more than C++ if I am wrting applications. So somtimes I have to look on the internet for some additional info to somthing I dont know as it my C books is dated 1994 and is quite old. But it taught me well.
    Double Helix STL

  11. #11
    Registered User
    Join Date
    May 2007
    Posts
    5
    Wow... lots of thoughts on the "C route to Java" comment! :-)

    Thanks, everyone, for the input. Found a copy of "The C Programming Langauge" online... so I'm trying some of its exercises as well. I used to own a copy of that many years ago...

    Jeffrey

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. getchar() problem
    By jlharrison in forum C Programming
    Replies: 6
    Last Post: 01-25-2006, 02:49 PM
  2. getchar buffer size
    By oncemyway in forum C Programming
    Replies: 3
    Last Post: 08-02-2005, 12:49 AM
  3. getchar() problem from K&R book
    By anemicrose in forum C Programming
    Replies: 13
    Last Post: 04-04-2004, 11:06 PM
  4. help with getchar lol
    By Taco Grande in forum C Programming
    Replies: 5
    Last Post: 03-18-2003, 09:25 PM
  5. Can anybody take a look at this?
    By TerryBogard in forum C Programming
    Replies: 10
    Last Post: 11-21-2002, 01:11 PM