Thread: Obscure loop using scanf and getchar functions - Program for reading int and double

  1. #1
    Registered User
    Join Date
    Feb 2018
    Posts
    8

    Question Obscure loop using scanf and getchar functions - Program for reading int and double

    Hi, guys.

    I have problems understanding this program.

    Code:
    /*
    
    
        By now you have probably experienced problems with scanf insofar as when an invalid character is typed things go drastically wrong. In “GETVAL.C” write and test two functions:
    
                    double get_double(void);
                    int get_int(void);
            
        which loop, prompting the user, until a valid double/valid integer are entered.
    
    
    */
    
    #include <stdio.h>
    
    
    //FUNCTION PROTOTYPES
    int get_int(void);
    double get_double(void);
    
    
    //MAIN FUNCTION
    int main(void)
    {
        int i;
        double d;
    
    
        printf("type an integer ");
        i = get_int();
        printf("the integer was %i\n", i);
    
    
        printf("type an double ");
        d = get_double();
        printf("the double was %lg\n", d);
    
    
        return 0;
    }
    
    
    //FIRST FUNCTION
    int get_int(void)
    {
        int result;
    
    
        printf("> ");
    
    
        while(scanf("%i", &result) != 1)
        {
            while(getchar() != '\n');
            printf("> ");
        }
    
    
        return result;
    }
    
    
    //SECOND FUNCTION
    double get_double(void)
    {
        double result;
    
    
        printf("> ");
    
    
        while(scanf("%lf", &result) != 1)
        {
            while(getchar() != '\n');
            printf("> ");
        }
    
    
        return result;
    }


    I have problems understanding this loop in both subordinate made functions.


    Code:
    while(scanf("%lf", &result) != 1)
        {
            while(getchar() != '\n');
            printf("> ");
        }
    Could you help me to understand? I've looked for additional information without success. I really don't get what's going there.

    Thanks in advanced.

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Let's see. The outer loop keeps repeating as long as scanf() fails to read a double. The inner loop's job is to clear stdin of all lingering line input, including the newline. Then a prompt is printed and the outer loop repeats.
    Devoted my life to programming...

  3. #3
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Hey there,

    The one thing that I can see that would trip up someone without a lot of experience is the ';' at the end of the while loop.

    Code:
    while(...);
    is the same as
    Code:
    while(...)
    {
    
    }
    i.e. Do nothing when looping.

    I would suggest that you put a few printfs in there and then try different inputs (like abc123, 123abc, ...)

    Code:
    #include <stdio.h>
    
    int main (void)
    {
        double result;
    
        int scanfResult;
    
        char getcharResult;
    
        printf("> ");
    
    
        while((scanfResult = scanf("%lf", &result)) != 1)
        {
    
            printf("scanfResult = %d\tresult = %lf\n", scanfResult, result);
    
            while((getcharResult = getchar()) != '\n')
            {
                printf("getchar() == \'%c\'\n",getcharResult);
            }
            printf("getchar() == \'\\n\'\n",getcharResult);
    
            printf("> ");
        }
    
        printf("scanfResult = %d\tresult = %lf\n", scanfResult, result);
    
        while((getcharResult = getchar()) != '\n')
        {
            printf("getchar() == \'%c\'\n",getcharResult);
        }
        printf("getchar() == \'\\n\'\n",getcharResult);
    
    
        printf("Press Enter to exit...");
        while(getchar() != '\n');
    
        return 0;
    }
    After you have seen how the scanf and getchar behaves, try re-reading the additional information - It will make more sense now that you have some experience
    Fact - Beethoven wrote his first symphony in C

  4. #4
    Registered User
    Join Date
    Feb 2018
    Posts
    8
    Ok, I've been studying a little further the secondary functions after reading your comments.

    Code:
    double get_double(void)
    {
        double result;
    
    
        printf("\n> ");
    
    
        while(scanf("%lf", &result) != 1)
        {
            while(getchar() != '\n');
            printf("> ");
        }
    
    
        return result;
    }
    What I was not understanding were the conditions inside the while. Let me see if I got this straight.

    Outer while. The scanf function is waiting for a double, in case a non-double is entered returns 0, which is compared with the given value 1. Zero means false, and 1 means true. If a double is entered, it returns the boolean value 1. Since 1 != 1 is false, then the while is terminated.

    Inner while. The getchar function can only accept chars. While only chars are entered, it will return 1, because getchar is working, is true. This is different than \n, in which case getchar() != \n is true, so the loop will continue. So, it will be possible to enter as many characters as wanted until a new line is entered, in which case the condition of \n != \n is false and the loop is terminated. After this, the character > is printed out and the condition in the outer loop is executed.

    I'm having trouble seeing how the condition of the outer loop works with the inner loop. I thought that C was a sequential (line 1 -> line 2 -> line 3 -> etc) programming language. Is the condition in the inner loop executed at the very same time touterter condition is executed?

    Thanks for your answers.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by carloswm85
    While only chars are entered, it will return 1, because getchar is working, is true. This is different than \n, in which case getchar() != \n is true, so the loop will continue.
    That is incorrect. If there is a character to read, getchar reads it as an unsigned char converted to int, then returns the result. Otherwise, getchar returns EOF. Therefore, it will not return 1 unless the character read as a value of 1 when read as an unsigned char.

    Quote Originally Posted by carloswm85
    I'm having trouble seeing how the condition of the outer loop works with the inner loop. I thought that C was a sequential (line 1 -> line 2 -> line 3 -> etc) programming language. Is the condition in the inner loop executed at the very same time touterter condition is executed?
    The outer loop reads the first part of the input entered by the user, then if that input is not in double format, the inner loop then reads and discards input until the newline that terminates the line of input is read.
    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

  6. #6
    Registered User
    Join Date
    Feb 2018
    Posts
    8
    Quote Originally Posted by laserlight View Post
    That is incorrect. If there is a character to read, getchar reads it as an unsigned char converted to int,
    So, what is the integer value that is reading? The ASCII character codes? (ie: 101 for A, etc)

    Quote Originally Posted by laserlight View Post
    then returns the result. Otherwise, getchar returns EOF. Therefore, it will not return 1 unless the character read as a value of 1 when read as an unsigned char.
    I'm not sure what you're trying to explain here. I speak Spanish, and I struggle sometimes with Englsih. For what you've written here, I understand that getchar returns 1 everytime that it reads a character, doesn't it? What happens if I enter instead of a character, the correct value (ie, an integer value)?

    Quote Originally Posted by laserlight View Post
    The outer loop reads the first part of the input entered by the user, then if that input is not in double format, the inner loop then reads and discards input until the newline that terminates the line of input is read.
    Ok. But what's the returning value of scanf every time the correct input is entered? And why? I've tried to found the original function of scanf without success.

    Thanks for your answers.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by carloswm85
    So, what is the integer value that is reading? The ASCII character codes? (ie: 101 for A, etc)
    It returns the value of the character read as an unsigned char (because char might be signed, in which case it is possible that the character might have a value outside of the range of char, and to avoid possible overlap with EOF, which is a negative integer), converted to int. The value of the character is indeed its value in whatever character representation used, which almost certainly means ASCII or something built on ASCII.

    Quote Originally Posted by carloswm85
    For what you've written here, I understand that getchar returns 1 everytime that it reads a character, doesn't it?
    No, I specifically said that getchar only returns 1 if the value of the character when read as an unsigned char is 1. In absolutely no other case does it ever return the value of 1. Compile and run this program:
    Code:
    #include <stdio.h>
    
    int main(void)
    {
        int c;
        printf("Enter a line of text: ");
        while ((c = getchar()) != '\n' && c != EOF)
        {
            printf("The value of '%c' is %d\n", c, c);
        }
        return 0;
    }
    Quote Originally Posted by carloswm85
    What happens if I enter instead of a character, the correct value (ie, an integer value)?
    If you do that, then the scanf call will read the value, hence the outer loop terminates without executing the inner loop. Therefore, there will be nothing to talk about concerning getchar.

    Quote Originally Posted by carloswm85
    But what's the returning value of scanf every time the correct input is entered? And why? I've tried to found the original function of scanf without success.
    scanf returns the number of items that were successfully read, i.e., in this case the format string is written to read one item, so if the read is successful, scanf will return 1.
    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

  8. #8
    Registered User
    Join Date
    Feb 2018
    Posts
    8
    Quote Originally Posted by laserlight View Post
    The outer loop reads the first part of the input entered by the user, then if that input is not in double format, the inner loop then reads and discards input until the newline that terminates the line of input is read.
    Got it. Thank you.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. scanf getchar
    By hit in forum C Programming
    Replies: 5
    Last Post: 08-21-2012, 02:47 AM
  2. getchar and scanf
    By begin in forum C Programming
    Replies: 9
    Last Post: 06-20-2010, 07:51 PM
  3. scanf, getchar, gets, etc. are ignored.
    By daltore in forum C Programming
    Replies: 19
    Last Post: 12-27-2007, 10:47 PM
  4. scanf and getchar
    By axe in forum C Programming
    Replies: 7
    Last Post: 01-11-2006, 04:45 AM
  5. my program skips scanf and getchar()
    By jk81 in forum C Programming
    Replies: 15
    Last Post: 11-29-2002, 05:54 PM

Tags for this Thread