Thread: Newbie question about getchar() behavior.

  1. #1
    Registered User
    Join Date
    Jun 2010
    Posts
    10

    Newbie question about getchar() behavior.

    Hello,

    I am a mid-thirties networking professional (Cisco, Juniper et al.) and I have recently caught the bug to learn how to program above and beyond some very noddy bash scripts I've created in the past. Therefore please excuse my post if it's something simple, but I'm trying to undertand what I'm seeing.

    I'm working through the CProgramming.com C Tutorial "Intro to C" section. In my attempt to use the concepts from the tutorial beyond the examples provided, I am trying to understand why I need two instances of the getchar() function within my exitprogram() function. Without two instances, the exitprogram() function returns back to main() and the user doesn't see the result from the inputfunction() calculation.

    If I comment out the inputfunction() call within alive() then I need to press enter twice before the program exits.

    I hope my explanation is clear and I have provided the program code below to refer to. Apologies for the insane level of commenting, however I figure if I get into a good practice now, whilst I may rationalise what I comment a little as I get more experience, from what I've read it's a good habit to get into.

    Thanks.

    Code:
    /*
    This program was written to show a basic set of C commands and syntax.
    */
    
    /*  Let's begin by bringing in the standard libraries we'll be using*/
    #include <stdio.h>
    #include <stdlib.h>
    
    int alive();                                                       /* Declare our function alive() */
    int exitprogram();                                                 /* Declare our function exitprogram() */
    int inputfunction();                                               /* Declare our function inputfunction() */
    
    int main()                                                         /* Function main() */
    {                                                                  /* This is the start of our main() function */
       alive();                                                        /* Let's call our function alive() */
       exitprogram();                                                  /* Let's call our function exitprogram() */
       return 0;                                                       /* Let's exit cleanly */
    }                                                                  /* This is the start of our main() function */
    
    int alive()                                                        /* Function alive() */
    {                                                                  /* This is the start of our alive() function*/
       system("clear");                                                /* Clear the screen using a system command "clear" */
       printf( "I am alive!  Beware.\n\n\n" );                         /* This is our main print statement */
       inputfunction();                                                /* Let's call our function inputfunction() */
       return 0;                                                       /* Let's exit cleanly */
    }                                                                  /* This is the end of our alive() function */
    
    int exitprogram()                                                  /* Function exitprogram() */
    {                                                                  /* This is the start of our exitprogram() function */
       printf( "Press enter to exit.\n" );                             /* Let's ask the user to do something */
       getchar();                                                      /* We'll wait for their input */
       getchar();                                                      /* We'll wait for their input */
       system("clear");                                                /* Clear the screen using a system command "clear" */
       printf( "Program exited successfully!\n\n\n" );                 /* Give our user a nice friendly message */
       return 0;                                                       /* Let's exit cleanly */
    }                                                                  /* This is the end of our exitprogram() function */
    
    int inputfunction()                                                /* Function inputfunction() */
    {                                                                  /* This is the start of our inputfunction() function */
       int variable_a, variable_b, variable_x;                         /* Declare our variables variable_a, variable_b and variable_x */
       variable_a = 0;                                                 /* Let's zero our variable variable_a */
       variable_b = 0;                                                 /* Let's zero our variable variable_b */
       variable_x = 0;                                                 /* Let's zero our variable variable_x */
       printf( "Please enter your first number: " );                   /* Ask the user to enter a number */
       scanf( "%d", &variable_a );                                     /* Store the user input into variable variable_a */
       printf( "Please enter your second number: " );                  /* Ask the user to enter a number */
       scanf( "%d", &variable_b );                                     /* Store the user input into variable variable_b */
       variable_x = variable_a + variable_b;                           /* Our variable variable_x the sum of variables variable_a and variable_b */
       printf( "The sum of your numbers is %d!\n\n\n", variable_x );   /* Print our variable variable_x */
       return 0;                                                       /* Let's exit cleanly */
    }                                                                  /* This is the end of our inputfunction() function */

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You might want to read SourceForge.net: Scanf woes - cpwiki.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Jun 2010
    Posts
    10
    Thanks Elysia. What I read on the link you provided made sense in general however some of the examples were a little over my head right now.

    I did some digging around and found I could add the following before the inputfunction() function returns to the alive() function:

    Code:
    fflush(stdin);
    This call appears to solve my problem. There might be a better way, but for a noddy like me it works.

    Thanks again.
    Last edited by Packeteer; 06-18-2010 at 05:54 AM. Reason: Typo.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    You can define you own, then go ahead and use that instead.

    Code:
    #define flush_stdin while( getchar() != '\n' );
    The preprocessor will then replace 'flush_stdin', in your code with the definition at compile time.

  6. #6
    Registered User
    Join Date
    Jun 2010
    Posts
    10
    Thanks again to both of you for the useful information and suggestions.

    Subsonics: I wasn't able to get your snippet of code working. I suppose I am too "new" at this to really know what to do with it. I'll play around more on the weekend.

    For now I'm content that I understand the possible buffer issues with fscanf() and why using fflush(stdin) is a no-no. I'm going through the if() statements tutorial now but I'm sure I'll be back with more q's as I delve deeper.

    Thanks again to you both.

  7. #7
    Registered User
    Join Date
    Jun 2010
    Posts
    45
    put this line at the top of your code

    #define flush_stdin while( getchar() != '\n' );

    and whenever you need to use fflush(stdin), just replace it with flush_stdin. it will do the exact same thing that you want it to, but the 2nd way is correct. wont go into the details but its better to get into good habits now than have to break them later

  8. #8
    Registered User matrixx333's Avatar
    Join Date
    Mar 2009
    Posts
    67
    Also another good habit to get into early:

    FAQ > What's the difference between... > main() / void main() / int main() / int main(void) / int main(int argc, char *argv[])

    Basically, you should include "void" as an argument to any function that is not being passed a value, like


    Code:
    int main(void) 
    {          
       alive();                                                        
       exitprogram();                                                  
       return 0;                                                 
    }                                                                
    
    int alive(void)                      
    {                                                             
       system("clear");                                               
       printf( "I am alive!  Beware.\n\n\n" );              
       inputfunction();                                               
       return 0;                                                    
    }                                                              
    
    int exitprogram(void)                                         
    {                                                             
       printf( "Press enter to exit.\n" );                         
       getchar();                                                
       getchar();                                      
       system("clear");                                       
       printf( "Program exited successfully!\n\n\n" );      
       return 0;                                      
    }
    etc......

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Packeteer
    why using fflush(stdin) is a no-no.
    Because fflush() is only defined for output streams and update streams for which the last operation was not input.

    As for the flush_stdin macro that has been suggested: that is up to you. If you find it strange, just write the while loop directly, or place it in a function, e.g.,
    Code:
    void flush_stdin(void)
    {
        int c;
        while ((c = getchar()) != '\n' && c != EOF);
    }
    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

  10. #10
    Registered User
    Join Date
    Jun 2010
    Posts
    10
    @ LordPc
    Thanks for the tip but I couldn't get the thing to compile even with your tips. I am a noob!

    @laserlight
    Thanks your alternative ended up working once I figured out that I needed to get rid of the #define directive I had tried earlier.

    @matrix333
    Much obliged. I am sure that over time I will come to master the nuances of C!

    @All
    Awesome forum btw. I was a little nervous posting but you've all been a great help! No doubt I'll be back with more "complex" stuff as I go along.

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Packeteer
    Thanks for the tip but I couldn't get the thing to compile even with your tips. I am a noob!
    My guess is that you tried to "call" the macro as if it were a function, i.e.,
    Code:
    flush_stdin();
    Whereas you really were supposed to write:
    Code:
    flush_stdin
    which looks rather strange, admittedly, but is correct and makes sense once you understand that it is macro replacement. Frankly, just using a function as in my example is fine.
    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
    Registered User
    Join Date
    Jun 2010
    Posts
    7

    Thumbs up

    Quote Originally Posted by matrixx333 View Post
    Also another good habit to get into early:

    FAQ > What's the difference between... > main() / void main() / int main() / int main(void) / int main(int argc, char *argv[])

    Basically, you should include "void" as an argument to any function that is not being passed a value, like


    Code:
    int main(void) 
    {          
       alive();                                                        
       exitprogram();                                                  
       return 0;                                                 
    }                                                                
    
    int alive(void)                      
    {                                                             
       system("clear");                                               
       printf( "I am alive!  Beware.\n\n\n" );              
       inputfunction();                                               
       return 0;                                                    
    }                                                              
    
    int exitprogram(void)                                         
    {                                                             
       printf( "Press enter to exit.\n" );                         
       getchar();                                                
       getchar();                                      
       system("clear");                                       
       printf( "Program exited successfully!\n\n\n" );      
       return 0;                                      
    }
    etc......

    Just to add to this post:
    Instead of returning 0 in these functions, you are better off declaring the return type as 'void'
    ex:
    Code:
    void someProcedure (void){
         do_something();
         do_something_else();
    }

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Just don't do it with main. It should return int.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Registered User
    Join Date
    Jun 2010
    Posts
    10
    Quote Originally Posted by laserlight View Post
    My guess is that you tried to "call" the macro as if it were a function, i.e.,
    Code:
    flush_stdin();
    Whereas you really were supposed to write:
    Code:
    flush_stdin
    which looks rather strange, admittedly, but is correct and makes sense once you understand that it is macro replacement. Frankly, just using a function as in my example is fine.
    You nailed it! Doh!

  15. #15
    Third Eye Babkockdood's Avatar
    Join Date
    Apr 2010
    Posts
    352
    Quote Originally Posted by matrixx333 View Post
    Also another good habit to get into early:
    Basically, you should include "void" as an argument to any function that is not being passed a value, like


    Code:
    int main(void) 
    {          
       alive();                                                        
       exitprogram();                                                  
       return 0;                                                 
    }                                                                
    
    int alive(void)                      
    {                                                             
       system("clear");                                               
       printf( "I am alive!  Beware.\n\n\n" );              
       inputfunction();                                               
       return 0;                                                    
    }                                                              
    
    int exitprogram(void)                                         
    {                                                             
       printf( "Press enter to exit.\n" );                         
       getchar();                                                
       getchar();                                      
       system("clear");                                       
       printf( "Program exited successfully!\n\n\n" );      
       return 0;                                      
    }
    etc......
    I don't see why people put "void" in the parenthesis. It's extremely redundant.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. if then else - newbie question
    By Penage in forum C Programming
    Replies: 3
    Last Post: 04-10-2010, 03:23 PM
  2. Newbie question, C #
    By mate222 in forum C# Programming
    Replies: 4
    Last Post: 12-01-2009, 06:24 AM
  3. Stupid Newbie question
    By TimL in forum C++ Programming
    Replies: 4
    Last Post: 07-22-2008, 04:43 AM
  4. Newbie with Very Newbie Question
    By Jedi_Mediator in forum C++ Programming
    Replies: 18
    Last Post: 07-01-2008, 08:00 AM
  5. newbie: array question :(
    By cstudent in forum C Programming
    Replies: 2
    Last Post: 04-09-2008, 06:46 AM