SOLVED - Validate user input

Thread Starter

Sparsh45

Joined Dec 6, 2021
143
I have written a C program that shows user entered option but I think it can be improved further.

C:
#include <stdio.h>

int main(void)

{

  char x;

  printf (" What's your ANSWER A, B, C, D : ");

  scanf("%c", &x);

  switch (x)

    {
         case 'A' :
                    printf(" Answer A \n");
                     break;
         case 'B' :
                    printf(" Answer B \n");
                    break;
         case 'C' :
                    printf(" Answer C \n");
                     break;
         case 'D' :
                    printf(" Answer D \n");
                    break;
         default :
                    printf(" Not Valid Answer  \n");      
    }

  return 0;
}
I think the two points below can improve the code

  • If the user enters a numeric value, it should be indicated that he has entered a numeric value and give a chance to enter a new value.

  • If the user enters a small letter it should be indicated that he has entered a small letter and give a chance to enter a new value.

I understand that when user enters a value, I need to check if there is a numeric value or not or it is not a lowercase letter.

I'm looking for help to improve the code. I don't understand how to write code for two verification.
 

BobTPH

Joined Jun 5, 2013
11,463
1. Change a lower case input to upper.
2. Check to see if it ‘is A’ through ‘D’. If not print an error message and prompt for input again.

Bob
 

Thread Starter

Sparsh45

Joined Dec 6, 2021
143
ok so first how to find if the input is numeric value or alphabet. The program works for alphabet.

But if the user enters a numeric value, how would this be tested in the program?
 

MrChips

Joined Oct 2, 2009
34,628
Rather than focusing on code, think of control structure.

1. prompt for answer
2. is it a valid answer?
3. if no, go back to 1.
 

Thread Starter

Sparsh45

Joined Dec 6, 2021
143
Rather than focusing on code, think of control structure.

1. prompt for answer
2. is it a valid answer?
3. if no, go back to 1.
There is an error in my code. May be scanf statement taking wrong input. i don't know why code print double line

C:
#include <stdio.h>

int main(void)
{
    char x;

     printf (" What's your ANSWER A, B, C, D : ");

    scanf("%c", &x);

     while (( x != 'A')&&( x != 'B')&&( x != 'C')&&( x != 'D'))
     {
             printf ("Wrong input Try again : ");

             scanf("%c", &x);
      }

    switch (x)

        {

         case 'A' :
                    printf("Answer A \n");
                     break;
         case 'B' :
                    printf("Answer B \n");
                    break;
         case 'C' :
                    printf("Answer C \n");
                     break;
         case 'D' :
                    printf("Answer D \n");
                    break;
      }

  return 0;
}
output :
What's your ANSWER A, B, C, D : j
Wrong input Try again : Wrong input Try again : C
Answer C
 

Ya’akov

Joined Jan 27, 2019
10,226
There is an error in my code. May be scanf statement taking wrong input. i don't know why code print double line

C:
#include <stdio.h>

int main(void)
{
    char x;

     printf (" What's your ANSWER A, B, C, D : ");

    scanf("%c", &x);

     while (( x != 'A')&&( x != 'B')&&( x != 'C')&&( x != 'D'))
     {
             printf ("Wrong input Try again : ");

             scanf("%c", &x);
      }

    switch (x)

        {

         case 'A' :
                    printf("Answer A \n");
                     break;
         case 'B' :
                    printf("Answer B \n");
                    break;
         case 'C' :
                    printf("Answer C \n");
                     break;
         case 'D' :
                    printf("Answer D \n");
                    break;
      }

  return 0;
}
output :
What's your ANSWER A, B, C, D : j
Wrong input Try again : Wrong input Try again : C
Answer C
Please investigate regular expressions as I mentioned above.
 

xox

Joined Sep 8, 2017
936
There is an error in my code. May be scanf statement taking wrong input. i don't know why code print double line


C:
#include <stdio.h>


int main(void)

{

    char x;


     printf (" What's your ANSWER A, B, C, D : ");


    scanf("%c", &x);


     while (( x != 'A')&&( x != 'B')&&( x != 'C')&&( x != 'D'))

     {

             printf ("Wrong input Try again : ");


             scanf("%c", &x);

      }


    switch (x)


        {


         case 'A' :

                    printf("Answer A \n");

                     break;

         case 'B' :

                    printf("Answer B \n");

                    break;

         case 'C' :

                    printf("Answer C \n");

                     break;

         case 'D' :

                    printf("Answer D \n");

                    break;

      }


  return 0;

}
output :

What's your ANSWER A, B, C, D : j

Wrong input Try again : Wrong input Try again : C

Answer C
What is happening here is that scanf first reads a character from the standard input device but then on the next iteration it tries to read the newline sequence that was generated whenever you pressed the "enter" key. So you really just need to consume any characters up and until that point before moving on.

In fact it might be a good idea to package all that up into function. Just construct a loop to invoke it, breaking out upon success:


Code:
#include <stdio.h>

int onechar(void) {
  int res = 0;
  size_t cnt = 0;
  char cur;
  while (scanf("%c", &cur) == 1) {
    if (cur == '\n')
      break;
    if (res == 0)  // This only ever happens once!
      res = cur;
    ++cnt;
  }
  if (cnt != 1)  // ie: Input can be neither empty nor multi-character
    return EOF;
  return res;
}

#include <ctype.h>

int main(void) {
  while (1) {
    printf(" What's your ANSWER A, B, C, D : ");
    int ans = toupper(onechar());
    if (ans != EOF && ans >= 'A' && ans <= 'D') {
      printf(" Answer: %c\n", ans);
      break;
    }
    puts("Error: Invalid selection!");
  }
  return 0;
}

A little more advanced approach might be to make things even more generic and reusable. Here's a function which reads a much wider range of types while embedding the validation loop internally:

Code:
#include <stdbool.h>
#include <stdio.h>

void prompt(const char* message,  // Optional, can be NULL
            void* address,
            const char* format,
            bool (*validate)(void*)) {  // Optional, can be NULL
  if (message == NULL)
    message = "Input";
  for (;;) {
    printf("%s: ", message);
    int scn = scanf(format, address);
    if (validate != NULL)
      if (!validate(address))
        scn = 0;
    size_t mor = 0;
    while (getchar() != '\n')
      ++mor;
    /*
     Return if no errors are encountered
    */
    if (scn == 1 && mor == 0)
      return;
    puts("Error: Invalid selection!");
  }
}

#include <ctype.h>

/*
 We'll plug this into the `prompt` function for both validation and conditioning
 (ie: converting to uppercase)
*/
bool is_ABCD(void* character) {
  char* ptr = character;
  *ptr = toupper(*ptr);
  return *ptr >= 'A' && *ptr <= 'D';
}

int main(void) {
  char inp;
  prompt("What's your ANSWER A, B, C, D", &inp, "%c", is_ABCD);
  printf("Answer: %c\n", inp);
  // Can also be used to input integers, etc...
  int val;
  prompt("Please input an integer", &val, "%d", NULL);
  printf("Integer: %d\n", val);
}
Hope that helps.
 

click_here

Joined Sep 22, 2020
548
There is an error in my code. May be scanf statement taking wrong input. i don't know why code print double line

C:
#include <stdio.h>

int main(void)
{
    char x;

     printf (" What's your ANSWER A, B, C, D : ");

    scanf("%c", &x);

     while (( x != 'A')&&( x != 'B')&&( x != 'C')&&( x != 'D'))
     {
             printf ("Wrong input Try again : ");

             scanf("%c", &x);
      }

    switch (x)

        {

         case 'A' :
                    printf("Answer A \n");
                     break;
         case 'B' :
                    printf("Answer B \n");
                    break;
         case 'C' :
                    printf("Answer C \n");
                     break;
         case 'D' :
                    printf("Answer D \n");
                    break;
      }

  return 0;
}
output :
What's your ANSWER A, B, C, D : j
Wrong input Try again : Wrong input Try again : C
Answer C
It will be the dangling newline

How do I avoid a "dangling" newline when reading single character user input?

Have a look at the link for flushing the input buffer :)
 
Top