Thread: Scanf

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    9

    Scanf

    I've the following issue.

    I have a do while loop where user is constantly prompted for 2 inputs at a time.

    Code:
    do {
    
    scanf("%d,%d" &a, &b)
    
    }while (a != 0)
    Example, user keys in the inputs
    6,9
    2,6
    4,8
    3,8
    0

    How can i re-code such that once 0 is detected, it will break the loop?

    I've to admit, this is a assignment and what've being taught is very limited up till this point.

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by meandmyipod View Post
    How can i re-code such that once 0 is detected, it will break the loop?
    If "a" is an integer type, that's what your loop should do. Unless...

    You might what to try checking exactly what is going on. Perhaps you have assumed something happens a certain way when it actually does not?

    Code:
    int c;
    do {
    	c = scanf("%d,%d" &a, &b);
    	printf("%d %d %d\n", c, a, b);
    } while (a != 0)
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Sep 2011
    Posts
    9
    Erm,

    To terminate the loop now, i'll need to key in 0 0 instead of only one 0.

    Eg,

    1 7
    2 8
    0 //I want it to break this way


    1 7
    2 8
    0 0 // This's what i need to do with my above code to terminate.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Well you can't just use scanf(), because you're trying to treat one of the inputs as optional.

    Consider something like this.
    Code:
    char buff[BUFSIZ];
    while ( fgets( buff, BUFSIZ, stdin ) != NULL ) {
      if ( sscanf(buff,"%d,%d", &a, &b ) == 2 ) {
        // success
      } else
      if ( sscanf( buff, "%d", &a ) == 1 && a == 0 ) {
        // just a 0 on a line by itself - exit
        break;
      } else {
        // something else
      }
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by meandmyipod View Post
    Erm,

    To terminate the loop now, i'll need to key in 0 0 instead of only one 0.

    0 0 // This's what i need to do with my above code to terminate.
    Erm, this might seem to be evidence of what I just mentioned:

    Quote Originally Posted by MK27 View Post
    Perhaps you have assumed something happens a certain way when it actually does not?
    Did you try adding reporting like I recommended? If that is too much effort for you to make, give up programming now.

    I can tell you that this:
    Code:
    #include <stdio.h>
    
    int main(void) {
    	int a, b, c;
    	do {
    		c = scanf("%d, %d", &a, &b);
    		printf("%d %d %d\n", c, a, b);
    	} while (a != 0);
    	return 0;
    }
    Works in the way you describe ("0" will end). Maybe the code you have posted is not the exact code you are using?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Salem View Post
    Well you can't just use scanf(), because you're trying to treat one of the inputs as optional.
    As long as the optional ones come after (as in this case) that should be okay, presuming the input buffer is flushed by a newline. Note the OP wants to use "0", not "0,0" but claims the later works while the former doesn't.

    Of course, if the inputs have ended up "out of predicted order", then you will have a problem. Methinks the OP should find out why that has happened. The other possibility is that the OS does not flush the input buffer on a newline, but I doubt that or the scanf() would not have worked in the first place.
    Last edited by MK27; 10-02-2011 at 10:08 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    Aug 2010
    Posts
    231
    Quote Originally Posted by Salem View Post
    Code:
    ...
    while ( fgets( buff, BUFSIZ, stdin ) != NULL ) {
      if ( sscanf(buff,"%d,%d", &a, &b ) == 2 ) {
    ...
    Wrong if user will put more than BUFSIZ-1 characters in inputbuffer.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    How so?

    Granted, if the user knows what the implementation value of BUFSIZ is, then they could press the space bar say BUFSIZ-5 times and type in 12345,6789 and get some weird ........ to happen.

    But that is why there is a final 'else' (which you nicely omitted in your quote before saying it was garbage), to catch all the nonsense input the user might try to type in.

    If you want to be pedantic, then you should be using strtol() / strtoul() instead of sscanf, since the latter does NOT detect overflow.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by meandmyipod View Post
    I've the following issue.

    I have a do while loop where user is constantly prompted for 2 inputs at a time.

    Code:
    do {
    
    scanf("%d,%d" &a, &b)
    
    }while (a != 0)
    Example, user keys in the inputs
    6,9
    2,6
    4,8
    3,8
    0

    How can i re-code such that once 0 is detected, it will break the loop?

    I've to admit, this is a assignment and what've being taught is very limited up till this point.
    Check the return value of scanf()...
    Code:
    int test;
    
    do 
      {
        test = scanf("%d,%d",&a,&b);
        // do something with a and b here
      }
    while(test == 2);
    This gives you a double advantage... first it will exit on 0 as you wanted... but it will also exit on any invalid input such as the user typing "fred" instead of a number.

    (The red bit up there is a link... click and read!)

  10. #10
    Registered User
    Join Date
    Aug 2010
    Posts
    231
    Quote Originally Posted by Salem View Post
    How so?
    You dont know what i mean.
    If a user put more than BUFSIZ-1 characters in inputbuffer, fgets keeps the '\n' and a next inputread will ignored.

  11. #11
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    Quote Originally Posted by BillyTKid View Post
    You dont know what i mean.
    If a user put more than BUFSIZ-1 characters in inputbuffer, fgets keeps the '\n' and a next inputread will ignored.
    Hmm....this post and your last one. Are you really going after Salem? Have fun....
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

  12. #12
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by BillyTKid View Post
    You dont know what i mean.
    If a user put more than BUFSIZ-1 characters in inputbuffer, fgets keeps the '\n' and a next inputread will ignored.
    Why would it ignore it?
    Code:
    #include<stdio.h>
    #undef BUFSIZ
    #define BUFSIZ 5
    int main( void )
    {
        char buff[BUFSIZ];
        int a, b;
        
        printf( "format is #,#\ngo:\n" );
        while ( fgets( buff, BUFSIZ, stdin ) != NULL ) {
            if ( sscanf(buff,"%d,%d", &a, &b ) == 2 ) {
                // success
                printf( "a: %d, b: %d\n", a, b );
            } else
            if ( sscanf( buff, "%d", &a ) == 1 && a == 0 ) {
                // just a 0 on a line by itself - exit
                break;
            } else {
                // something else
                printf( "something else:\'%s\'\n", buff );
            }
        }
        return 0;
    }
    Try it.


    Quzah.
    Hope is the first step on the road to disappointment.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by BillyTKid
    If a user put more than BUFSIZ-1 characters in inputbuffer, fgets keeps the '\n' and a next inputread will ignored.
    Rather, the single line of input would appear to be multiple lines, leading to an incorrect interpretation of the data. This could well be caught by the error checking anyway, and even when it isn't, the program would not suffer from writing to the array out of bounds, although it would give incorrect output. Given that what the OP has been "taught is very limited up till this point", and that the only improvement comes from error handling for less likely cases, I would say this is an acceptable example.
    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

  14. #14
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    Quote Originally Posted by BillyTKid View Post
    You dont know what i mean.
    If a user put more than BUFSIZ-1 characters in inputbuffer, fgets keeps the '\n' and a next inputread will ignored.
    Quote Originally Posted by quzah View Post
    Why would it ignore it?
    Code:
    #include<stdio.h>
    #undef BUFSIZ
    #define BUFSIZ 5
    int main( void )
    {
        char buff[BUFSIZ];
        int a, b;
        
        printf( "format is #,#\ngo:\n" );
        while ( fgets( buff, BUFSIZ, stdin ) != NULL ) {
            if ( sscanf(buff,"%d,%d", &a, &b ) == 2 ) {
                // success
                printf( "a: %d, b: %d\n", a, b );
            } else
            if ( sscanf( buff, "%d", &a ) == 1 && a == 0 ) {
                // just a 0 on a line by itself - exit
                break;
            } else {
                // something else
                printf( "something else:\'%s\'\n", buff );
            }
        }
        return 0;
    }
    Try it.


    Quzah.
    Quote Originally Posted by laserlight View Post
    Rather, the single line of input would appear to be multiple lines, leading to an incorrect interpretation of the data. This could well be caught by the error checking anyway, and even when it isn't, the program would not suffer from writing to the array out of bounds, although it would give incorrect output. Given that what the OP has been "taught is very limited up till this point", and that the only improvement comes from error handling for less likely cases, I would say this is an acceptable example.
    Hmm........................
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

  15. #15
    Registered User
    Join Date
    Oct 2011
    Location
    india
    Posts
    18
    by using the single scanf(),you cannot terminate the pgm by inputting one zero...because the compiler will check the while() loop only after 2nd input is provided.you can proceed like this:
    Code:
    do 
     {
    
      scanf("%d" &a,);
     if(a==0)
      break;
     scanf("%d",&b);      
     }while (a!=0);

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. \n after scanf
    By shonit in forum C Programming
    Replies: 2
    Last Post: 03-04-2008, 07:52 AM
  2. while scanf
    By PUI in forum C Programming
    Replies: 3
    Last Post: 10-06-2006, 11:24 AM
  3. First scanf() skips next scanf() !
    By grahampatten in forum C Programming
    Replies: 5
    Last Post: 08-17-2004, 02:47 AM
  4. scanf - data is "put back" - screws up next scanf
    By voltson in forum C Programming
    Replies: 10
    Last Post: 10-14-2002, 04:34 AM
  5. scanf
    By jwhitaker3 in forum C Programming
    Replies: 2
    Last Post: 09-06-2002, 12:52 PM