Thread: scanf skips lines of code in DOS using Dev-C++ and Windows XP

  1. #1
    Registered User
    Join Date
    Dec 2008
    Posts
    3

    scanf skips lines of code in DOS using Dev-C++ and Windows XP

    --EDIT--
    The problem with the third snippet has been resolved and thus removed from the thread! It wasn't the syntax error identified here (but thanks a bunch for catching that, that was kind of embarassing...), so leaving it in here would just confuse readers. However, I still do not know how I would go about removing the newline buffer from scanf without the if statement below (please read my background). Changed portion at the bottom of first post in dark green.

    Hello, all!

    I have incredibly recently begun my C education, as I am preparing myself for my first computer science class next quarter, and some minor familiarity with C programming is necessary for the class. Given that, my programs and problems are very simple.

    My problem is this: scanf seems to cause my programs to skip over certain parts of themselves.

    either a) scanf(); will skip a part of itself, or b) scanf(); will skip a getchar(); statement later.

    Here is a comparison with two smooth programs, I am having trouble with the third, and an instance of skipping getchar(); appears in the second.
    (sorry, indentation removed in posting)

    My first program (who would have thought) was Hello, World! As it only uses printf, it does not skip lines. It runs smoothly. The syntax is as follows:

    ------------------------------------------------------------------------
    Code:
    #include <stdio.h> /* Includes printf definition */
    
    int
    main(void) 
    {
               /* Print Hello, world! */
               printf("Hello, world!\n");
               
               getchar(); /*pauses the program so output can be read*/
               return(0);
               
    }
    -------------------------------------------------------------
    The getchar(); statement at the end of the program suspends it so the user can view output. This program is completely functional.

    The next program I used calculated the diameter, circumference, and area of a circle, given a radius from the user. The syntax of the program is as follows:


    Code:
    int 
    main(void)
    {
               double RAD,    /* input - radius */
                      DIAM,   /* output - diameter */
                      CIRCUM, /* output - circumference */
                      AREA;   /* output - area */
                      
               /* Obtain the radius of the circle */
               printf("Please enter the radius of the circle.\n");
               scanf("&#37;lf", &RAD);
               
               /* Given the radius, calculate the diameter, circumference, and area, respectively */ 
               DIAM = 2 * RAD;
               CIRCUM = 2 * PI * RAD;
               AREA = PI * RAD * RAD;
               
               /* Display the diameter, circumference, and radius, respectively */
               printf("The diameter of the circle is %f units.\n", DIAM);
               printf("The circumference of the circle is %f units.\n", CIRCUM);
               printf("The area of the circle is approximately %f units.\n", AREA);
               
               
               getchar(); /* Delay the program so the user can view the data */
               getchar(); /* one getchar did not delay the program, two did */
               return(0); 
               
    }
    ------------------------------------------------------
    If I used only one getchar();, the program would close immediately. At first I didn't care, but I know this is important and is going to come back to hurt me. Are there other ways to pause a program so a user can view output?

    I use Windows XP and am compiling in Dev-C++ 4.9.9.2. My programs execute in the command prompt.

    Thanks for your time!
    Last edited by jenovanomusuko; 12-19-2008 at 07:24 PM. Reason: Responding to Responses - Correcting Syntax

  2. #2
    Registered User
    Join Date
    Dec 2008
    Posts
    32
    I'll address your first issue and you can probably take it from there.

    The reason you found you needed two getchar()'s in your second code snippet was because the newline character was still in the buffer after your scanf(). scanf stops scanning when it finds what it's looking for. You need to address that using any method you like.

    My personal preference (and emphasis on preference here) is to use fgets followed by sscanf, like so:
    Code:
    char buffer[256];
    float val1, val2;
    if (fgets(buffer,256,stdin))
    {
        if (sscanf(buffer,"&#37;f %f",&val1,&val2)==2)
        {
              /* do something */
        }
    }
    Or you can just adjust the format string of your scanf calls, up to you. The approach I outlined though does have its advantages when doing more than simple value reads like this.

  3. #3
    Registered User
    Join Date
    Jan 2007
    Location
    Euless, TX
    Posts
    144
    For your third problem, I'm surprised it reads 2, since the second and third values are not declared!
    Code:
    char FIRST, 
    MIDDLE, 
    LAST;

    while your statements are asking for and trying to display
    Code:
    printf("instructions for user");
    
    scanf("&#37;c%c%c", &FIRST, &SEC, &THIRD); 
    
    
    printf("%c%c%c", FIRST, SEC, THIRD);
    BTW it works fine for me on VC++ 6.0 (without second getchar() )

  4. #4
    Registered User
    Join Date
    Dec 2008
    Posts
    3
    Thank you for such quick responses! However, some issues are still on the prowl. First, please look at the edit to see what's going on in the third snippet from previously. Secondly, I do not know how to do this:

    Quote Originally Posted by core_cpp View Post
    Or you can just adjust the format string of your scanf calls, up to you. The approach I outlined though does have its advantages when doing more than simple value reads like this.
    As I am trying to be as minimal as possible and haven't reached the chapter on if statements in my book yet, how would I format the string of my scanf calls to eliminate the new line from the buffer? I removed the last new line from my printf before the first getchar, but that is clearly not what is being mentioned here.

    Thanks again!

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    The correct way to solve this problem is to actually run your program in the command prompt. You know, the black box with the blinky thing. Type the name of your program (you may have to cd to the correct directory first) and off you go.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    No, the correct way is to use a proper IDE, such as Visual Studio that does not close the program after it's finished executing.
    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.

  7. #7
    Registered User
    Join Date
    Dec 2008
    Posts
    3
    Quote Originally Posted by tabstop View Post
    The correct way to solve this problem is to actually run your program in the command prompt. You know, the black box with the blinky thing. Type the name of your program (you may have to cd to the correct directory first) and off you go.
    I actually tried using the Run command to run these outside of Dev, and they still close without two getchar()'s. It doesn't really influence my program that heinously - it's just a nuisance is all.

  8. #8
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404
    You actually need to physically open up the command prompt, not just execute your program from the run text box. And as tabstop said, you will probably need to cd to the directory in which your program is contained.

  9. #9
    Registered User
    Join Date
    Nov 2008
    Location
    Phoenix
    Posts
    70
    I'm a C noob myself, having just finished my first semester. So with that in mind, take this information as you will. Experts, please be gentle.

    Quote Originally Posted by jenovanomusuko View Post
    If I used only one getchar();, the program would close immediately. At first I didn't care, but I know this is important and is going to come back to hurt me. Are there other ways to pause a program so a user can view output?

    I use Windows XP and am compiling in Dev-C++ 4.9.9.2. My programs execute in the command prompt.

    Thanks for your time!
    In general terms, given the setup you are using (almost the same as mine, which is Vista & Dev-C++), what you could do is:

    In your includes, put:

    Code:
    #include <stdlib.h>
    Then right before your return statement, put:

    Code:
    system("PAUSE");
    After the program is finished running, it won't simply disappear on you. It will stay open until you press something. It will say "press any key to continue . . . _". It's handy for testing purposes. In your completed program, if you don't need to do any such thing, you can just remove the system pause line and the stdlib include, if you don't need it for anything else.

    However:

    Quote Originally Posted by jenovanomusuko View Post
    As I am trying to be as minimal as possible and haven't reached the chapter on if statements in my book yet, how would I format the string of my scanf calls to eliminate the new line from the buffer? I removed the last new line from my printf before the first getchar, but that is clearly not what is being mentioned here.
    In the context of this specific program and the question you are asking about the buffer, try doing this (which worked for me, when I compiled and ran your program):

    After the includes, put:

    Code:
    #define FLUSH while (getchar() != '\n')
    Now erase one of your getchar statements, or comment it out. Then right before the one remaining getchar, put:

    Code:
    FLUSH;
    And you're fine. I prefer the system pause method over the getchar method for when I'm too lazy to just manually open a command window, but I mention the FLUSH thing because that's a little bit of code that you may find useful in the future for situations where you need to clear the buffer due to funky and unexpected things happening (like needing to do two getchars).

    To the best of my knowledge, what the little FLUSH thing does is keep getting characters from the buffer (it's a 'while' loop) until it reaches the new line. Since the semicolon immediately follows the close parentheses of the 'while' expression, making it a null/empty statement, it simply gets rid of the char that it just took from the buffer. Over and over again, until the buffer is empty. This means the buffer is clean for your one getchar statement.

    I'm still not 100% clear on this, but this is the way I understood it.
    Last edited by Sorin; 12-21-2008 at 03:05 AM.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Again, for the command thingy... use a proper IDE such as Visual Studio. It can force the window to stay open, or you can use its debugger and put a breakpoint on the closing line to force the window to remain open. No need for unportable system commands nor any dirty tricks to force it to stay open nor any use of a command prompt.

    The flushing is only necessary for things such as scanf. Another (better way imho) is to use fgets, then convert it to whatever format you need using strtoX (X being d or l or whatever you need). No need to worry about crap in the input buffer.
    Also, it is better to create a function named like FlushInput instead of a macro.
    Last edited by Elysia; 12-21-2008 at 03:41 AM.
    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.

Popular pages Recent additions subscribe to a feed