Thread: Validation

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

    Validation

    Code:
    do
    			{
    				// display title
    				printf("Individual Salesman Commission\n");
    				printf("==============================\n");
    
    
    				// show tip for first input
    				if (*tip == 1)
    				{
    					// display tip 
    					printf("Tip: Just input the number instead of the whole id.\n\n");
    				}
    
    
                    // prompt and read salesman id
                    printf("Salesman ID (NO.): ");
                    
    				// if it is not a valid input 
                    if (scanf("%d",&stop) == NULL)
                    {
                        valid = 0; // continue loop process
                        printf("Invalid input. Please input again.\n\n");
    					//system("pause"); // freeze display message
    					printf("\nPress Enter to continue...\n"); 
    					getchar();
    					getchar(); // prompt user
                    }
                    else
                        valid = 1; // end loop process
    
    
    				// clear input buffer
    				while ((ch = getchar()) != '\n' && ch != EOF);
    
    
    				// clear screen display  
    				system("cls");
                } while (valid == 0); // loop if the input is invalid
    1) Why it straight away end the loop after I used getchar() rather than system("pause")?
    2) How can I validate number+character/string such as 1asd?

  2. #2
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Consider this simple example.
    Code:
    int x;
    scanf("%d",&x);
    I press a number and then i hit enter.So now the buffer of the stdin has the number and the newline character.scanf will read the number but the newline character stays there waiting to get read.So when you use getchar you read the newline character.So you may eat the newline character by an extra call of getchar or with scanf .

    About the validation or use the isdigit ,isalpha etc functions or read input with fgets and check yourself what is in the input

  3. #3
    Registered User
    Join Date
    Jun 2012
    Posts
    127
    1) You mean after getchar() get the newline, it will continue to enter non-stop? So, how many getchar() u put is still the same result.

    Code:
    do
    			{
    				// display title
    				printf("Individual Salesman Commission\n");
    				printf("==============================\n");
    
    
    				// show tip for first input
    				if (*tip == 1)
    				{
    					// display tip 
    					printf("Tip: Just input the number instead of the whole id.\n\n");
    				}
    
    
                    // prompt and read salesman id
                    printf("Salesman ID (NO.): ");
                    
    				// if it is not a valid input 
    				if ( (scanf("%d",&stop)) == NULL)
                    {
                        valid = 0; // continue loop process
                        printf("Invalid input. Please input again.\n\n");
    					//system("pause"); // freeze display message
    
    
    					// clear input buffer
    					while ((ch = getchar()) != '\n' && ch != EOF);
    
    
    					printf("\nPress Enter to continue...\n"); 
    					getchar(); // prompt user
                    }
                    else
                        valid = 1; // end loop process
    
    
    				// clear input buffer
    				//while ((ch = getchar()) != '\n' && ch != EOF);
    
    
    				// clear screen display  
    				system("cls");
                } while (valid == 0); // loop if the input is invalid

  4. #4
    Registered User
    Join Date
    Jun 2012
    Posts
    127
    2) isdigit is not working as scanf("%d") only read the digit and skips the char/string.

  5. #5
    Registered User
    Join Date
    Jun 2012
    Posts
    82
    (2) Add this into your else statement

    Code:
    while ((ch = getchar()) != '\n')
    {
       if(ch > 1)
       {
          printf("Error! Re-enter : ");
          scanf("%d", &stop);
        }
    }
    Regarding how it works, if I'm not mistaken. It's like this,
    let's say user input 2a

    2 is took by scanf, 'a' and '\n' are left in the buffer, and when getchar gets 'a', if(ch > 1) , which means, if 97 > 1 (the ascii value for 'a' is 97) then print out error message and ask the user to re-enter.
    Last edited by xeon321; 11-15-2012 at 11:26 AM.

  6. #6
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Quote Originally Posted by ulti-killer View Post
    2) isdigit is not working as scanf("%d") only read the digit and skips the char/string.
    Maybe i wasn't clear enough.Sorry for that :/

    First the input matter.
    Assume that i want to read two user's inputs..First input,then print ,then input again and then print again..So i have to scanf,then printf, then scanf again and then printf for last time.
    So i could do something like this..
    Code:
    #include <stdio.h>
    
    int main(void)
    {
        char choice,anotherChoice;
    
        printf("Please type c , h or i\n");
        scanf("%c",&choice);
    
        if(choice == 'c') {
           printf("User typed c\n");
        }
        else if(choice == 'h') {
           printf("User typed h\n");
        }
        else if(choice == 'i') {
           printf("User typed i\n");
        }
    
        printf("Please type c , h or i\n");
        scanf("%c",&anotherChoice);
    
        if(anotherChoice == 'c') {
           printf("User typed c\n");
        }
        else if(anotherChoice == 'h') {
           printf("User typed h\n");
        }
        else if(anotherChoice == 'i') {
           printf("User typed i\n");
        }
    
    
        return 0;
    }
    And the output
    Code:
    Macintosh-c8bcc88e5669-9:~ usi$ gcc -Wall px.c -o px
    Macintosh-c8bcc88e5669-9:~ usi$ ./px
    Please type c , h or i
    c
    User typed c
    Please type c , h or i
    Macintosh-c8bcc88e5669-9:~ usi$
    What is the problem?That code "skipped" my second scanf, so without the program to wait for user to input for second time it terminated bypassing the user's input.So what happened?
    I press a character and then i hit enter.So now the buffer of the stdin has the character and the newline character.scanf will read the character but the newline character stays there waiting to get read.So the next scanf has already data to process and that it is what is doing.It reads the newline character, does not find a match in the if/else that follow and reaches return 0 of main function..

    Now if we look into the documentation of scanf we will find out that if we leave a space between the double quotes and the percentage operator, then scanf will "eat" the newline character will is exactly what we want
    So in the code that i posted above i only modify the second scanf ,leaving the space i quoted above.The result is
    Code:
    scanf(" %c",&anotherChoice);
    Now the output is this
    Code:
    Macintosh-c8bcc88e5669-9:~ usi$ pico px.c
    Macintosh-c8bcc88e5669-9:~ usi$ gcc -Wall px.c -o px
    Macintosh-c8bcc88e5669-9:~ usi$ ./px
    Please type c , h or i
    h
    User typed h
    Please type c , h or i
    i
    User typed i
    Macintosh-c8bcc88e5669-9:~ usi$
    Alternative solution.We know that a newline character is in the stdin buffer, but we do not want it to be handled as user's input.Thus we can instead of modifying the second scanf to write a line of code with getchar (or equivalently getc(stdin) ) that will eat this newline character.Then the unmodified second scanf will do what we want to.
    In code (intermediate a getchar and leave the second scanf as it was in the first piece of code)
    Code:
    #include <stdio.h>
    
    int main(void)
    {
        char choice,anotherChoice;
        int c;
    
        printf("Please type c , h or i\n");
        scanf("%c",&choice);
    
        if(choice == 'c') {
           printf("User typed c\n");
        }
        else if(choice == 'h') {
           printf("User typed h\n");
        }
        else if(choice == 'i') {
           printf("User typed i\n");
        }
    
        c = getchar();
    
        /* Newline's ascii code is 10 */
        if( c == 10 )
            printf("\nNewline was indeed in the stdin buffer before 2nd scanf\n\n");
    
        printf("Please type c , h or i\n");
        scanf("%c",&anotherChoice);
    
        if(anotherChoice == 'c') {
           printf("User typed c\n");
        }
        else if(anotherChoice == 'h') {
           printf("User typed h\n");
        }
        else if(anotherChoice == 'i') {
           printf("User typed i\n");
        }
    
    
        return 0;
    }
    Output :
    Code:
    Macintosh-c8bcc88e5669-9:~ usi$ gcc -Wall px.c -o px
    Macintosh-c8bcc88e5669-9:~ usi$ ./px
    Please type c , h or i
    c
    User typed c
    
    Newline was indeed in the stdin buffer before 2nd scanf
    
    Please type c , h or i
    h
    User typed h
    Macintosh-c8bcc88e5669-9:~ usi$
    Oh also do fell into the trap of fflush . When i first encountered this problem , everybody said flush the stdin...
    This leads to unexpected behavior... I suggest you read this short lines of explanation here .

    Now , the isdigit and the isalpha

    .. actually the links are pretty good..so check them and if you have questions ask

    I also stated the fgets function which is highly recommended by me.Notice in the link what is stated about newline character.
    It will return to you to an array all the input given.This is very useful, because it is like you have parsed the input.
    Example
    Code:
    #include <stdio.h>
    
    int main(void)
    {
        char buf[10];
        int i;
    
        printf("Please type an alpharithmetic input\n");
        fgets(buf , 10 , stdin);
    
        for( i = 0 ; i < 10 ; i++)
        {
           if(buf[i] == '\0' || buf[i] == '\n')
              break;
           printf("buf[%d] = %c\n",i,buf[i]);
        }
    
        return 0;
    }
    Output
    Code:
    Macintosh-c8bcc88e5669-9:~ usi$ pico px.c
    Macintosh-c8bcc88e5669-9:~ usi$ ./px
    Please type an alpharithmetic input
    sam1
    buf[0] = s
    buf[1] = a
    buf[2] = m
    buf[3] = 1
    Macintosh-c8bcc88e5669-9:~ usi$
    If you get a number in the input, it is very possible to want its value.For this operation use atoi

    Also in case you find yourself in meeting gets function , be kind with her and say bb .
    The reason is here .

    Hope this helps

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Validation
    By ulti-killer in forum C Programming
    Replies: 8
    Last Post: 11-15-2012, 12:06 AM
  2. validation
    By chodmama in forum C Programming
    Replies: 3
    Last Post: 02-20-2006, 01:05 AM
  3. validation
    By Ideswa in forum C++ Programming
    Replies: 11
    Last Post: 01-30-2006, 01:01 PM
  4. validation
    By blanny in forum C Programming
    Replies: 9
    Last Post: 03-05-2004, 07:43 PM
  5. need help in validation
    By dholman in forum C Programming
    Replies: 2
    Last Post: 01-08-2004, 09:27 AM