Menu

Getchar() required to follow scanf(.....)

2007-08-09
2012-09-26
  • Nobody/Anonymous

    Dev-C++ Version 4.9.9.2
    Windows XP

    I am new to C programming and I found what seems to be an unusual requirement in Dev-C++ that is not required in Microsoft Visual Studio 6.0. Dev-C++ seems to require that I follow scanf(....) with getchar() in this program. The progam is not very sophisticated so I may it poorly structured. It did complile however, so I thought that would indicate that the structure was not too bad.

    Sorry, but I could not figure out how to include line numbers. I have a bitmap image but I was unable to attach it to this thread.

    If you comment out line 39 <getchar()> the program will not work. It is my understanding that scanf(...) should have the same effect as getchar() with regard to holding the console window until the user responded. It does not do that with Dev-C++.

    Did I do something wrong here?

    /* This program inputs a single character A, B, C or D and outputs a number
    corresponding to the character.

    for input character = A the output is 1
    for input character = B the output is 2
    for input character = C the output is 3
    for input character = D the output is 4
    for input character = E...Z or other the output is 0
    */

    /Henry Santana
    Created: 8/6/2007
    Last revision: 8/9/2007
    /

    include <stdio.h>

    int Output, ReturnValue;
    char InChar;

    int TestSwitch(char Character)
    {
    switch(Character)
    {
    case 'A': ReturnValue=1; break;
    case 'B': ReturnValue=2; break;
    case 'C': ReturnValue=3; break;
    case 'D': ReturnValue=4; break;
    default: printf("Illegal character input %c \n", Character); ReturnValue=0;
    }
    return ReturnValue;
    }

    main()
    {
    printf("Enter A, B, C or D \n");
    scanf("%c", &InChar);

    getchar(); //Why is this needed?
    //*********
    /
    getchar() required in Dev-C++.
    Not required in Microsoft Visual Studio 6.0
    */
    //
    **********
    Output=TestSwitch(InChar);
    printf("Output = %d \n", Output);

    / getchar() will hold the window open waiting for user input. This is
    sometimes necessary when the window closes too quickly before it can be
    read. To close the window press ENTER.
    /
    printf("Press <ENTER> to close window");
    getchar();
    }

     
    • Nobody/Anonymous

      It was great to hear from you folks. Evidently I have a lot to learn.

      I chose a slightly more complex program than "Hello World" because it is a little more challenging, it wasn't designed to be useful. I had a lot of fun debugging it (It had a lot of errors).

      I learned that for programs like this Basic is better. If you want to see how a good basic can be, check out MikroBasic at www.mikroe.com (Nice IDE too). Unfortunately it just generates code for microprocessors only and has no user console I/O functions but the the syntax is really nice.

      Thanks to all for the prompt response. Best wishes to everyone.

      H. Santana

       
      • Wayne Keen

        Wayne Keen - 2007-08-10

        Actually, I first learned BASIC back in 1975, and used it on and off for the next
        25+ years. I did a LOT of work with it.

        For a long time, it was my first language.

        I am reluctant to say any language is "better" than another - they are each
        strong in certain ways. Adding new languages helps you, even if you never
        use them for much. They help you understand the languages you do use better.

        I learned Python just for the heck of it, and it is one of my primary languages.

        Stick with it, and you will be better and richer for the experience.

        Wayne

         
    • Anonymous

      Anonymous - 2007-08-09

      The line:

      scanf("%c", &InChar);

      extracts exactly one character from the input buffer, but none of the stdin functions return until you press <newline> - the input buffer is line oriented and makes no characters available until a whole line is received. So when you press:

      A<ENTER>

      you place two characters in the buffer.

      Your getchar() trick is flawed however. If a ham fisted user typed:

      AA<ENTER>

      the getchar() would extract the second 'A' only, leaving you just where you were before!

      A better solution is:

      while( getchar() != '\n' ){ /flush line buffer/ } ;

      I find it hard to believe that it is "Not required in Microsoft Visual Studio 6.0" since they use the exact same C runtime library! I just tried it in VC++ 2005 and it exhibits the same (correct) behaviour.

      Clifford

       
      • Anonymous

        Anonymous - 2007-08-09

        Just to be clear (in case it wasn't), when there are characters remaining in the buffer, subsequent scanf("%c", &InChar); calls are satisfied immediatly by whatever remains in the buffer, so fall straight through without waiting for more input.

        The only way to make it work with stdio calls is to switch the console to character rather than line mode - doing that is platform specific and I am not sure that Windows or teh C runtime library even supports such a mode. The alternative is to use Win32 console API calls rather than stdio, which are not line buffered (but are much more cumbersome to use): http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/console_functions.asp

        Clifford

         
    • Wayne Keen

      Wayne Keen - 2007-08-09

      Please keep in mind that Dev-C++ is just an IDE, a fancy editor.

      The compiler it uses is GCC, so anything you run into with respect to why the compiler
      does something is better throught of as "Why does GCC do this?" rather than "Why does
      Dev-C++" do this?"

      This might seem like a symantic quibble, or an attempt to dodge blame, but understanding
      this enables you to ask questions that get you, either through searching or posting, better
      answers, faster.

      One other point. Visual C++ 6 is a compiler that is almost 10 years old. It is old enough
      that it predates the ANSI standard for the C++ language. There are a number of things that VC6
      does that are no longer correct by the language standard. If you find differences between
      what VC6 does, and a more modern compiler (like GCC 3.4 that Dev uses), then the odds are
      pretty good that VC6 is doing it wrong.

      Wayne

       
    • Anonymous

      Anonymous - 2007-08-09

      BTW, compiling simply means that he code is valid code. It says nothing about the quality or structure.

      The only real issue I have with your code since you mentioned it is that all your variables, with the exception of the parameter "Character" are global variables, and none of them need to be - they are never accessed by more than one function so can be local to where they are used. Always aim to use the use the more restrictive scope where possible.

      Making ReturnValue global, and then using it as a return value is a real howler! The caller sees both the return value and the global - you don't need both and should prefer the first ;-) After the TestSwitch() call both the globals Output and ReturnValue contain the same value.

      I'm sure it is hardly the point of your exercise, but the entire body of TestSwitch() could be replaced with just:

      return Character - 'B' ;

      and yield the same numerical result. But then TestSwitch() would be somewhat a misnoma! ;-) Can you tell I'm bored!?

      Clifford

       
      • Wayne Keen

        Wayne Keen - 2007-08-09

        Want to help me with some boat wake interpolation stuff?

        Jest kidd'in

        ;)

        Wayne

         

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.