Thread: If user enters wrong information in scanf

  1. #1
    Registered User
    Join Date
    Jun 2004
    Posts
    93

    If user enters wrong information in scanf

    Well this is a trivial piece of code that I'm working on just to understand the concepts of switch statements, and a bunch of other junk as I move along through it.

    Basically the basics of C.

    For this code however:

    Code:
    #include <stdio.h>
    
    int main () {
    
    	char response;
    
    	printf("This program is going to figure out how many days are left until your birthday.\n");
    	printf("\nDo you agree? (Y/N)");
    	
    	scanf("%c", &response);
    				
    		switch (response) {
    
    			case 'Y':
    			case 'y':
    				printf("Good job you crazy bastard.\n");
    				break;
    
    			case 'N':
    			case 'n':
    				printf("You flying asshat, get the hell out of here.\n");
    				return -1;
    				break;
    
    			default:
    				printf("Come on give me a Y or an N.\n");
    				/*while statement, an if statement, another scanf, what the hell do I do*/
    			}
    
    	return 0;
    
    }
    How do I correct the user if he entered another letter at the beginning? I tried throwing an if statement in there before the switch, and it didn't do much good. A while statement won't cover all 4 of the possible responses.

    I'm not really sure what to do if the user enters a number or something to guide him the right way.

    I'm working on it as I post this, but any ideas or responses are most welcomed.

    Thanks.

  2. #2
    Registered User pinko_liberal's Avatar
    Join Date
    Oct 2001
    Posts
    284
    Put it in a do while loop
    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    int main (void) {
    
    	char response;
    
    	printf("This program is going to figure out how many days are left until your birthday.\n");
    	printf("\nDo you agree? (Y/N)");
    
    	do{
    		scanf("%c", &response);
    	        response=toupper(response);
    		switch (response) {
    
    			case 'Y':
    				printf("Good job you crazy bastard.\n");
    				break;
    
    			case 'N':
    				printf("You flying asshat, get the hell out of here.\n");
    				return -1;
    				break;
    
    			default:
    				printf("Come on give me a Y or an N.\n");
    				/*while statement, an if statement, another scanf, what the hell do I do*/
    				break;
    			}
    	} while( (response != 'Y') && (response != 'N'));
    
    	return 0;
    
    }
    The one who says it cannot be done should never interrupt the one who is doing it.

  3. #3
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    Ah thanks man.

    The only problem with that is that it prints out the default in the switch twice when you err more than once, since it has to go through it all.

    I'll try to figure it out, if anyone has an idea let me know.

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    That's because you're leaving the newline in the input stream. Why don't you just use fgetc or getchar since all you're doing it reading one key?
    Code:
    int c, x;
    c = getchar( );
    while( (x=getchar( )) != '\n' && x != EOF ) ); /* clear out the newline and extra characters */
    switch( c )
    {
        ...
    }
    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    Quote Originally Posted by quzah
    That's because you're leaving the newline in the input stream. Why don't you just use fgetc or getchar since all you're doing it reading one key?
    Code:
    int c, x;
    c = getchar( );
    while( (x=getchar( )) != '\n' && x != EOF ) ); /* clear out the newline and extra characters */
    switch( c )
    {
        ...
    }
    Quzah.
    Awesome idea, but seeing as I've never used either of them before I wouldn't have known to use it lol. I'm pretty new to this.

    I will use them, and find out what they do.

    Could you elaborate a bit on what you mean by leaving the newline in the input stream? I assume it means I am giving the user the option of inputting a newline or something, but have no solid idea.

    Thanks a lot man.
    Last edited by Beast(); 06-10-2004 at 11:25 PM.

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Ok, you read something with scanf, pressing enter when you do so, but you don't actually read the enter from the stream, so it sits there, waiting for you to call some input-reading function, where it pops up. Try this:
    Code:
    #include <stdio.h>
    int main( void )
    {
        int one, enter;
        printf("Press a key and hit enter. Just one key for this demo: ");
        one = getchar( );
        enter = getchar( );
    
        printf(" You chose %c, followed by you hitting enter, giving us '%c'.\n", one, enter );
        return 0;
    }
    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    Thanks man, I'm going to play around with that as soon as I get a chance.

  8. #8
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751
    here's an option
    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    
    int main () {
    
    	char response;
    
    	printf("This program is going to figure out how many days are left until your birthday.\n");
    	printf("\nDo you agree? (Y/N)");
    	
    	while ( (scanf(" %s", &response))){
    				
    		switch (tolower(response)) {
    
    		//	case 'Y':
    			case 'y':
    				printf("Good job you crazy bastard.\n");
    				break;
    
    		//	case 'N':
    			case 'n':
    				printf("You flying asshat, get the hell out of here.\n");
    				getchar();getchar();/* so pauses so can see message*/
    				return -1;
    				break;
    
    			default:
    				printf("Come on give me a Y or an N.\n");
    				break;
    				
    			}
    }
    
    	return 0;
    
    }

    reads strings instead of characters. its not perfect though if u play around you'll find out. basically scanf sucks for input, if you do use u have to use it carefully by checking its return value. check the c faq
    Warning: Opinions subject to change without notice

    The C Library Reference Guide
    Understand the fundamentals
    Then have some more fun

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    here's an option
    Code:
    char response;
    ...
    while ( (scanf("%s", &response))){
    Well I suppose if you call crashing your program an option...

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

  10. #10
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Here's yet another option:
    Code:
    #include <ctype.h>
    #include <stdio.h>
    
    int
    valid(
      char *option
      )
    {
      /* More checking can easily be added here */
      return toupper(option[0]) == 'Y' || toupper(option[0]) == 'N';
    }
    
    int
    main(void)
    {
      char choice[BUFSIZ];
    
      printf("Type Y or N: ");
      fflush(stdout);
      while (!fgets(choice, sizeof choice, stdin) || !valid(choice)) {
        printf("Invalid input, try again: ");
        fflush(stdout);
      }
      switch (toupper(choice[0])) {
        case 'Y':
          /* Yadda yadda */
          break;
        case 'N':
          /* Yadda yadda */
          break;
      }
    
      return 0;
    }
    By using fgets you avoid any scanf nastiness as well as low level fgetc problems with extraneous characters.

    >while ( (scanf(" %s", &response))){
    scanf is allowed to return EOF if an input failure occurs before any conversions are made. Because EOF is not 0, your test would succeed and then proceed to do Bad Things.
    My best code is written with the delete key.

  11. #11
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751
    scanf is allowed to return EOF if an input failure occurs before any conversions are made. Because EOF is not 0, your test would succeed and then proceed to do Bad Things.
    can you give me an example. what you mean input failure? i'm reading a string.
    BTW: he hasn't started the fgets and those advance form of input yet, that's why we was wondering about scanf and how to use it properly.
    Warning: Opinions subject to change without notice

    The C Library Reference Guide
    Understand the fundamentals
    Then have some more fun

  12. #12
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >can you give me an example. what you mean input failure? i'm reading a string.
    Run the following and give the keyboard command for EOF (ctrl+z or ctrl+d are most common):
    Code:
    #include <stdio.h>
    
    int
    main(void)
    {
      char s[10];
    
      printf("%d\n", scanf("%9s", s));
    
      return 0;
    }
    >that's why we was wondering about scanf and how to use it properly.
    scanf is probably the most advanced of the standard input functions because it's so complex and difficult to get right.
    My best code is written with the delete key.

  13. #13
    mov.w #$1337,D0 Jeremy G's Avatar
    Join Date
    Nov 2001
    Posts
    704
    For error checking and prevention of bad user input, I prefer displaying threatening and or belittleing prompts--thus scaring or humiliating the user into entering the correct input!

    example:
    Listen here you mucas pea-brained little insignificant ........ant of a human being. If you think you can manage this simple task, such that even a retarded chipmunk could perform, press the Y or N key now. If not, then do yourself a favor, unplug your computer and go jump off a bridge into freeway traffic.
    Press Y or N now:
    Amazingly, my cs teacher said that was an inappropriate solution, and no matter how closely it may ring to the truth, a nicer kindler gentler prompt message should always be used.
    c++->visualc++->directx->opengl->c++;
    (it should be realized my posts are all in a light hearted manner. And should not be taken offense to.)

  14. #14
    Quote Originally Posted by caroundw5h
    here's an option
    Code:
    #include <stdio.h>
    
    int main () {
    
    	char response;
    
    	while ( (scanf(" %s", &response))){
    /* ... */
            }
    
    	return 0;
    }
    Sounds terrible to me. The "%s" will try to convert the input to a string. Imagine you just hit 'y'<ENTER>. You will get a 'y' at 'response', and a 0 at response + 1 (I assume you know what a C-string is). The problem is that response + 1 is not defined. Writing to an undefined memory location invokes an undefined behaviour. It's a serious bug.

    At minimum, you want ;

    Code:
    	char response [2];
    
    	scanf(" %s", response);
    but using "%s" without a limit is dangerous (the gets() problem)
    Code:
    	scanf(" %1s", response);
    but it's hard to maintain (but there are some ugly tricks). For all these reasons (among others), the good way to get a line from a user (or more generally from a stream) is to use fgets() or a smart function of yours based on it.
    Emmanuel Delahaye

    "C is a sharp tool"

  15. #15
    Registered User
    Join Date
    Jun 2004
    Posts
    277
    Code:
    scanf("%c", &response);
    		
    /*NAME  toupper, tolower - convert letter to upper or lower case
                                                                                                                     
    SYNOPSIS
           #include <ctype.h>
           int toupper(int c);
           int tolower(int c);
                                                                                                                     
    DESCRIPTION
           toupper()  converts  the letter c to upper case, if possible.
                                                                                                                     
           tolower() converts the letter c to lower case,  if  possible.
                                                                                                                     
           If  c is not an unsigned char value, or EOF, the behaviour
           of these functions is undefined.
                                                                                                                     
    RETURN VALUE
           The value returned is that of the converted letter,  or  c
           if the conversion was not possible.
    */
                   responce = toupper(response);		
    		switch (response) {
    
    			case 'Y':
    			//case 'y': now it can be removed
    				printf("Good job you crazy bastard.\n");
    				break;
    
    			case 'N':
    			//case 'n': now it can be removed
    				printf("You flying asshat, get the hell out of here.\n");
    				return -1;
    				break;
    
    			default:
    				printf("Come on give me a Y or an N.\n");
    /*while statement, an if statement, another scanf, what the hell do I do*/
    			}
    
    	return 0;
    
    }
    Last edited by Maragato; 06-16-2004 at 02:30 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. God
    By datainjector in forum A Brief History of Cprogramming.com
    Replies: 746
    Last Post: 12-22-2002, 12:01 PM
  2. Special Allegro Information
    By TechWins in forum Game Programming
    Replies: 12
    Last Post: 08-20-2002, 11:35 PM
  3. Replies: 6
    Last Post: 07-10-2002, 07:45 PM
  4. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM
  5. C++ Help
    By ravie23 in forum C++ Programming
    Replies: 0
    Last Post: 12-18-2001, 02:50 AM