Thread: Validate user input

  1. #1
    Registered User
    Join Date
    Jun 2012
    Posts
    127

    Validate user input

    Code:
    #include <stdio.h> 
    #include <stdlib.h> 
    
    int main ( void )
    {
      char yesno;
    
      // Prompt and read whether the user want to continue or stop the program
        printf("Continue (Y/N)? ");
        scanf("%c",&yesno);
        fflush(stdin);
        printf("\n");
    
      // Loop if the user input the character other than Y, y, N and n
      while (yesno != 'Y' && yesno != 'y' && yesno != 'N' && yesno != 'n')
        {
            printf("Invalid input. Please input again\n");
            printf("Continue (Y/N)? ");
            scanf("%c",&yesno);
            fflush(stdin);
            printf("\n");
        }
    
      system("pause");
      return 0;
    }
    It can't go into the loop if I type "y2222", "n1sass2","yyyyyyyy", "nnnnnnnnn" or any charcter start from "Y","y","N" or"n" plus any character, number or symbol. How to fix it? Thanks.

  2. #2
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    If you input y2222 then yesno holds the y.So in line 15 the statement is false,so we don't enter the loop.Isn't that expected?

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Please don't do this as it results in undefined behaviour since fflush is not defined for input streams:
    Code:
    fflush(stdin);
    There are a few alternatives, and these are related to your question. For example, after reading the character, you could have a loop that reads and discards characters until a newline is found.
    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

  4. #4
    Registered User
    Join Date
    Jun 2012
    Posts
    127
    Quote Originally Posted by std10093 View Post
    If you input y2222 then yesno holds the y.So in line 15 the statement is false,so we don't enter the loop.Isn't that expected?
    How can I get into the loop even the input is "y2222"?

    Quote Originally Posted by laserlight View Post
    Please don't do this as it results in undefined behaviour since fflush is not defined for input streams:
    Code:
    fflush(stdin);
    There are a few alternatives, and these are related to your question. For example, after reading the character, you could have a loop that reads and discards characters until a newline is found.
    1)What is the alternative besides fflush(stdin)?
    2)
    Code:
    int flag=0;/*This will us if there is something wrong with the input*/
            char example;
      
            printf("Enter Y : ");
      
            while (1)
            {
                example=getchar();
                if(example == '\n')/*enter*/
                    break;
                if(example != 'Y' && example != 'y')
                    flag=1;
            }
      
            if(flag)
                printf("Oops! Wrong entry!");
    There is a solution that achieve some of my goal but when type in "yyyyyyyyyy" it doesn't output "Oops! Wrong entry!".

  5. #5
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    What is the alternative besides fflush(stdin)?
    FAQ > Why fflush(stdin) is wrong - Cprogramming.com

  6. #6
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Quote Originally Posted by ulti-killer View Post
    How can I get into the loop even the input is "y2222"?
    This line
    Code:
    while (yesno != 'Y' && yesno != 'y' && yesno != 'N' && yesno != 'n')
    says that is the first character of the input is NOT Y and it is not y and it is not N AND it is not n ,then we are going to enter the loop.Better tell me what is your goal,so i can help you

  7. #7
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by ulti-killer View Post
    There is a solution that achieve some of my goal but when type in "yyyyyyyyyy" it doesn't output "Oops! Wrong entry!".
    You have to check if the first character is 'y' and the second is '\n' if you just want to have a single 'y' in the input line.

    Bye, Andreas

  8. #8
    Registered User
    Join Date
    Jun 2012
    Posts
    127
    Quote Originally Posted by std10093 View Post
    This line
    Code:
    while (yesno != 'Y' && yesno != 'y' && yesno != 'N' && yesno != 'n')
    says that is the first character of the input is NOT Y and it is not y and it is not N AND it is not n ,then we are going to enter the loop.Better tell me what is your goal,so i can help you
    My goals are
    1) When the user input other than Y, y , N and n, the program will show Invalid input. Please input again.
    2) The program will only terminate when the user input n or N.

  9. #9
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    I've told you already that you have to check if the first character is one of "YyNn" and the second one is the newline-character.

    Here is one possible solution:
    Code:
    #include <stdio.h>
    #include <string.h>
     
    int main(void)
    {
        int answer;
    
        do 
        {
            printf("Continue (Y/N)? ");
            answer = getchar();
            if (!(strchr("YyNn", answer) && getchar() == '\n'))
            {
                puts("Invalid answer!");
                if (answer != '\n')
                    while (getchar() != '\n')
                        ;
                answer = 0;
            }
        } while (answer != 'N' && answer != 'n');
    
        return 0;
    }
    Do you understand it?

    Bye, Andreas

  10. #10
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Quote Originally Posted by ulti-killer View Post
    My goals are
    1) When the user input other than Y, y , N and n, the program will show Invalid input. Please input again.
    2) The program will only terminate when the user input n or N.
    You have to imagine that when a user inputs something,then this is saved at an inbox buffer.getchar,goes at his buffer and gets a char(apparently :P )It will take the 1st character of that buffer.Then this character will be discarded from the buffer,so next time getchar is going to fetch a char from that buffer,it is going to get the 2nd character of what the user inputs.
    e.g.
    Code:
    ...
    int c;
    c = getchar();
    while(c != '\n')
    {
         printf("%c\n",c);
         c = getchar();
    }
    ...
    Try to input something and see what this code does.If you understand this i believe that you can write code to satisfy your needs.I suggest you try it be your one and do not look at Andreas post.Try it by your one,and then compare it with Andreas post,in order to learn

  11. #11
    Registered User
    Join Date
    Jun 2012
    Posts
    127
    Quote Originally Posted by AndiPersti View Post
    I've told you already that you have to check if the first character is one of "YyNn" and the second one is the newline-character.

    Here is one possible solution:
    Code:
    #include <stdio.h>
    #include <string.h>
     
    int main(void)
    {
        int answer;
    
        do 
        {
            printf("Continue (Y/N)? ");
            answer = getchar();
            if (!(strchr("YyNn", answer) && getchar() == '\n'))
            {
                puts("Invalid answer!");
                if (answer != '\n')
                    while (getchar() != '\n')
                        ;
                answer = 0;
            }
        } while (answer != 'N' && answer != 'n');
    
        return 0;
    }
    Do you understand it?

    Bye, Andreas
    Can somebody explains the code in detail? I can't understand at all.

  12. #12
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Line 10: Prompts the user for input
    Line 11: Receives user input (reads first character from input buffer)

    Line 12: This is where the fun begins.

    "strchr()" checks a given string (first argument) for an occurance of a specific character (second argument). It returns a char pointer - if that specific character has been found, this pointer will point to the location of the found character; if it has not been found, then this pointer will be null.

    In this context, the "strchr()" function is comparing the user input against a string constant. If the user input "answer" is not found in the comparison string "YyNn" (which holds all the inputs you consider valid), then the function returns a NULL pointer.

    If "answer" does match one of the acceptable characters ("YyNn"), it will return a pointer with a value.

    In this example, we don't care where the location of that character is, we just want to make sure it's in there (not NULL).

    So in our "if" statement, we have...

    Code:
    (strchr("YyNn", answer) && getchar() == '\n')
    If "answer" is in the string (not null, or true) AND the next character is a newline (true), then this whole expression is TRUE.
    If "answer" is not in the string (null, or false), then the whole expression is FALSE.
    If the next character is not a newline, then the whole expression is FALSE.

    Within the "if" statement, the result of this expression is negated:

    Code:
    !(strchr("YyNn", answer) && getchar() == '\n')
    If the input is valid, we have:

    Code:
    if(!TRUE)
    ... which means the "if" argument evaluates to false and lines 13 through 19 are skipped. If the user input is 'N' or 'n', we break the loop and exit. Otherwise, we jump back to line 10 and continue.

    If the input is not valid, we have:

    Code:
    if(!FALSE)
    ... which meas the "if" argument evaluates to true, in which case, we print our "invalid input" message to the screen (line 14) and continue through the body of the "if" statement block:

    - Line 15: If the user input was just a newline (enter pressed with no characters), then we just set it to zero and re-start the loop.
    - Line 16: If the user input was not just a newline, the "while" loop just eats up any extra characters in the input buffer until it reaches the newline.
    - Line 17: Null statement - nothing happens in the body of the "while" loop, as all the action is taking place in the argument to the "while" loop.
    - Line 18: Set the variable "answer" to zero.

    Then we just loop back to the beginning again.
    Last edited by Matticus; 07-12-2012 at 11:34 AM.

  13. #13
    Registered User
    Join Date
    Feb 2011
    Posts
    52
    @ Matticus: The effort is really praiseworthy.

    @ ulti-killer: U seem to be a beginner, perhaps the following code would be easier for u.


    Code 1:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
     
    int main ( void )
    {
      char yesno[3], ch;
     
      // Prompt and read whether the user want to continue or stop the program
        printf("Continue (Y/N)? ");
      
     
      // Loop if the user input the character other than Y, y, N and n
      while (1)
        {
    	fgets(yesno,3,stdin);
            printf("\n");
    	if(yesno[1]=='\n')
    		if(yesno[0] == 'y' || yesno[0] == 'Y' || yesno[0] == 'N' || yesno[0] == 'n' )
    			break;
      		
    	if(yesno[1]!='\n')
    		while (ch=getchar() != '\n');      
    	printf("Invalid input. Please input again\n");
            printf("Continue (Y/N)? ");
           
        }
     
      system("pause");
      return 0;
    }

    Code 2:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
     
    int main ( void )
    {
      char yesno;
     
      // Prompt and read whether the user want to continue or stop the program
        printf("Continue (Y/N)? ");
        yesno=_getche();
        fflush(stdin);
        printf("\n");
     
      // Loop if the user input the character other than Y, y, N and n
      while (yesno != 'Y' && yesno != 'y' && yesno != 'N' && yesno != 'n')
        {
            printf("Invalid input. Please input again\n");
            printf("Continue (Y/N)? ");
            yesno=_getche();
            fflush(stdin);
            printf("\n");
        }
     
      system("pause");
      return 0;
    }

  14. #14
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    @ Avenger625: Good point, a simpler approach would be much more beneficial for a beginner.

    At a glance, your "code 1" seems much friendlier.

    I would suggest, however, that you modify your "code 2" to remove the "fflush(stdin)" as this will result in undefined behavior and is bad practice (Why fflush(stdin) is wrong).

  15. #15
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    @Matticus: Thanks for the explanation :-)

    @Avenger625: Your first code works basically but I have found two small things:
    1)
    Code:
    while (ch=getchar() != '\n');
    Because of operator precedence getchar() != '\n" is evaluated first and then assigned to ch. But you don't really need ch (and you don't use it anywhere else in the program) thus
    Code:
    while (getchar() != '\n');
    has the same effect.

    2)
    If the user enters an empty line (just presses enter) s/he has to press enter a second time without any explanations - been there, done that :-)

    Code2: I'm not sure if ulti-killer wants an unportable solution using _getche.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 9
    Last Post: 06-16-2012, 09:18 AM
  2. Validate input value
    By aladin in forum C Programming
    Replies: 1
    Last Post: 03-21-2009, 09:41 AM
  3. Replies: 15
    Last Post: 01-11-2008, 03:57 PM
  4. How to Validate an Input
    By slowcoder in forum C Programming
    Replies: 12
    Last Post: 05-17-2007, 07:33 PM
  5. Validate a user input integer?
    By criticalerror in forum C++ Programming
    Replies: 20
    Last Post: 12-07-2003, 08:30 PM