Validation of integer with character input in C program - c

I write this program to do validation of selection (integer type variable) that entered by users. But the problem is after a valid input, the next invalid input (e.g: character type variable) will not be stored in the integer variable (selection). How can I solve this?
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#pragma warning (disable:4996)
void main()
{
int selection;
while (1)
{
while (1)
{
printf("Enter Your Selection (0-4) > ");
scanf("%d", &selection);
rewind(stdin);
if (!selectionCheck(&selection, 0, 4))
printf("Invalid\n");
else break;
}
printf("Success\n");
}
system("pause");
}
int selectionCheck(int *input, int min, int max)
{
char str[100] = "";
itoa(*input, str, 10);
if (isdigit(str[0]))
{
if (*input < min || *input > max)
return 0;
else return 1;
}
else
{
return 0;
}
}

Some notes:
1) You aren't checking the scanf() return value, and this is very usable: the negative return means that the entered characters can't be converted to int (because of "%d" format), and the return value equal 0 means that the input is empty (no characters entered).
2) In case that the user entered wrong character(s) (not digit(s)), the input buffer will remain busy until you read it in other way. Good idea is to use additional scanf("%s") here to read any characters as string, so buffer will be empty after this call. Using rewind() is not enough here.
3) There is no need to additional checking of input in selectionChecking() for isdigit(), because "%d" format in scanf() doesn't allow to read anything else but number.
4) There is no need to pass pointer to selection value in selectionChecking() call - it will be enough to pass it as value.
So, try this below:
// declaration of 'selectionCheck()'
int selectionCheck(int input, int min, int max);
void main()
{
int selection;
while (1)
{
while (1)
{
printf("Enter Your Selection (0-4) > ");
int ret = scanf("%d", &selection);
if (ret < 0) // invalid characters on input
{
printf("Invalid characters\n");
scanf("%s"); // empty buffer, reading it as string and putting readed characters to nowhere ;)
continue; // go to top of loop
}
if (ret == 0) // empty input
{
printf("No (empty) input\n");
continue; // go to top of loop
}
// here 'ret' is greather than 0, so valid number was entered
if (selectionCheck(selection, 0, 4)) // is value between 0 and 4 ?
break; // yes, success, break current loop!
printf("Invalid value\n");
}
printf("Success\n");
}
system("pause");
}
int selectionCheck(int input, int min, int max)
{
if (input < min || input > max)
return 0;
else
return 1;
}
Of course, you can write 'selectionCheck()' more condensed:
int selectionCheck(int input, int min, int max)
{
return (input < min || input > max) ? 0 : 1;
}
or simply:
int selectionCheck(int input, int min, int max)
{
return (input >= min && input <= max);
}

Related

how to get program to accept only positive integer values in c

writing a program that will be finding min, max, avg of values entered by user. Having trouble writing something that will check to make sure there are only postive integers entered and produce an error message. heres my for statement that is reading the input so far:
for (int value = 0; value <= numofvals; ++value) {
printf("Value %d: %f\n", value, val_input);
scanf("%f", &val_input);
}
mind you I've been learning code for about 3 weeks and was just introduced to loops this week so my understanding is rudimentary at best!
First, don't use scanf. If stdin doesn't match what it expects it will leave it in the buffer and just keep rereading the same wrong input. It's very frustrating to debug.
const int max_values = 10;
for (int i = 0; i <= max_values; i++) {
int value;
if( scanf("%d", &value) == 1 ) {
printf("Got %d\n", value);
}
else {
fprintf(stderr, "I don't recognize that as a number.\n");
}
}
Watch what happens when you feed it something that isn't a number. It just keeps trying to read the bad line over and over again.
$ ./test
1
Got 1
2
Got 2
3
Got 3
foo
I don't recognize that as a number.
I don't recognize that as a number.
I don't recognize that as a number.
I don't recognize that as a number.
I don't recognize that as a number.
I don't recognize that as a number.
I don't recognize that as a number.
I don't recognize that as a number.
Instead, use fgets to reliably read the whole line and sscanf to parse it. %f is for floats, decimal numbers. Use %d to recognize only integers. Then check if it's positive.
#include <stdio.h>
int main() {
const size_t max_values = 10;
int values[max_values];
char buf[1024];
size_t i = 0;
while(
// Keep reading until we have enough values.
(i < max_values) &&
// Read the line, but stop if there's no more input.
(fgets(buf, sizeof(buf), stdin) != NULL)
) {
int value;
// Parse the line as an integer.
// If it doesn't parse, tell the user and skip to the next line.
if( sscanf(buf, "%d", &value) != 1 ) {
fprintf(stderr, "I don't recognize that as a number.\n");
continue;
}
// Check if it's a positive integer.
// If it isn't, tell the user and skip to the next line.
if( value < 0 ) {
fprintf(stderr, "Only positive integers, please.\n");
continue;
}
// We got this far, it must be a positive integer!
// Assign it and increment our position in the array.
values[i] = value;
i++;
}
// Print the array.
for( i = 0; i < max_values; i++ ) {
printf("%d\n", values[i]);
}
}
Note that because the user might input bad values we can't use a simple for loop. Instead we loop until either we've read enough valid values, or there's no more input.
Something easy like this may work for you:
int n;
int ret;
for (;;) {
ret = scanf("%d", &n);
if (ret == EOF)
break;
if (ret != 1) {
puts("Not an integer");
for (;;)
if (getchar() == '\n')
break;
continue;
}
if (n < 0) {
puts("Not a positive integer");
continue;
}
printf("Correct value %d\n", n);
/* Do your min/max/avg calculation */
}
/* Print your results here */
This is just an example and assumes you do not need to read floating point numbers and then check if they are integers, as well as a few other things. But for starters, it is simple and you can work on top of it.
To break out of the loop, you need to pass EOF (typically Ctrl+D in Linux/macOS terminals, Ctrl+Z in Windows ones).
An easy and portable solution
#include <limits.h>
#include <stdio.h>
int get_positive_number() {
char buff[1024];
int value, ch;
while (1) {
printf("Enter positive number: ");
if (fgets(buff, 1023, stdin) == NULL) {
printf("Incorrect Input\n");
// Portable way to empty input buffer
while ((ch = getchar()) != '\n' && ch != EOF)
;
continue;
}
if (sscanf(buff, "%d", &value) != 1 || value < 0) {
printf("Please enter a valid input\n");
} else {
break;
}
}
return value;
}
void solution() {
// Handling malformed input
// Memory Efficient (without using array to store values)
int n;
int min = INT_MAX;
int max = INT_MIN;
double avg = 0;
printf("Enter number of elements: ");
scanf("%d", &n);
getc(stdin);
int value;
for (int i = 0; i < n; i++) {
value = get_positive_number();
if (value > 0) {
if (min > value) {
min = value;
}
if (max < value) {
max = value;
}
avg += value;
}
}
avg = avg / n;
printf("Min = %d\nMax = %d\nAverage = %lf\n", min, max, avg);
}
int main() {
solution();
return 0;
}
Output:
Enter number of elements: 3
Enter positive number: 1
Enter positive number: 2
Enter positive number: a
Please enter a valid input
Enter positive number: -1
Please enter a valid input
Enter positive number: 1
Min = 1
Max = 2
Average = 1.333333

How do you print different things depending the user input?

First, I apologize if the question doesn't make sense as my English isn't that good...
My question is, how do we print out different things depending on the user input?
What I'm trying to do is: when user inputs integer, the program prints out the inputted number. When the user inputs something that's not integer (like symbols and characters), the program prints out "not integer".
my current idea (pseudo-code) is as follows:
`int main(){
int value;
printf("Enter numbers");
scanf("%d", &value);
if(value is integer){
printf("%d", value);
} else {
printf("not integer");
}
return 0;
}`
what gets me is the scanf; by using %d, I'm assuming that the user will input an integer values, but the user can input values that are not integers so I can't make a comparison using the if statement if( value is integer). How can I make a comparison that will determine whether the inputted value is integer or not?
I don't know if this is a good thing or not.
You can use ASCII to check if the input type is an integer or not
(between 48 - 57 in ASCII)
it will be like this
char value;
int flag = 0; //to check true or false (0 means false, and 1 means true)
printf("Enter numbers");
scanf("%c", &value);
for(int i = 48; i <= 57; i++){
if(value == i){
flag = 1;
break;
}
}
if(flag == 1){
printf("%c", value);
} else {
printf("not integer");
}
How do you print different things depending the user input?
Step 1: Read the line of user input
char buf[100];
if (fget(buf, sizeof buf, stdin)) {
// something was entered
Step 2: test the string
char *end;
long value = strtol(buf, *end);
// If the end is the same as the beginning, no conversion occurred.
if (end == buf) {
puts("not integer");
}
printf("%ld\n", value);
}
}
Additional code could look for input that occurred after the integer. Also code could test for a large number that overflowed the long range.
The code is as follows. It caters for different situations like inputting negative numbers and decimal numbers:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main() {
char input[20];
int wrongFlag = 0;
scanf("%s", input);
if (input[0] == '0' && strlen(input) > 1) {
wrongFlag = 1;
//for number starts with 0, and string length>1 eg: 010
}
for (int i = 0; i < strlen(input); i++) {
if (i == 0 && (input[i] == '-' && strlen(input) > 2 && input[i + 1] == '0')) {
//check first round only: negative number with length >2 and starts with 0 eg: -010.
wrongFlag = 1;
continue;
}
if (i != 0 && !isdigit(input[i])) {
//check following rounds, check if it is not digit
wrongFlag = 1;
break;
}
}
if (wrongFlag) {
printf("Not integer");
}
else {
printf("integer");
}
return 0;
}
Try this it works for me.
#include<stdio.h>
#include<string.h>
int main()
{
int i;
char value[50];
int len;
printf("Enter maximum 50 digits\n");
/* enter the values you wanted*/
printf("Enter the value: ");
gets(value);
len = strlen(value);
/*it will iterate upto the end of the user input*/
for(i=0;i<len;i++)
{
if(48<value[i] && value[i]<=57)
{
if(i==(len-1))
printf("It's an integer");
}
else{
printf(" Not an integer");
break;
}
}
return 0;
}

How to prevent non-numeric input in C?

I wrote a small C program which will get an input from the user and check if the input is even or odd.
#include<stdio.h>
int main()
{
int n;
printf("Enter an integer number: ");
scanf("%d",&n);
if(n%2 == 0)
{
printf("\n%d is an EVEN number.\n",n);
}
else
printf("\n%d is an ODD number.\n",n);
return 0;
}
but when I enter an alphabet or a symbol, it shows the output as 0 and says input is EVEN. How can I prevent user from entering alphabets and symbols? What's the easiest way to do that?
You have to check the return value of scanf. From the documentation:
Return Value
Number of receiving arguments successfully assigned, or EOF if read failure occurs before the first receiving argument was assigned.
Applied to your code:
#include <stdio.h>
#include <stdlib.h>
int
main()
{
int n;
printf("Enter an integer number: ");
if (scanf("%d", &n) != 1)
{
printf("This is not a number.\n");
return EXIT_FAILURE;
}
else if (n % 2 == 0)
{
printf("\n%d is an EVEN number.\n", n);
return EXIT_SUCCESS;
}
else
{
printf("\n%d is an ODD number.\n", n);
return EXIT_SUCCESS;
}
}
Simply check the return value of scanf - it'll tell you how many format objects were successfully parsed. In this case, it'll return 1 if it could parse an int, and 0 if it couldn't.
If the input is an integer, then scanf() will return 1 so you can check
if (scanf("%d", &integer) != 1)
invalidInput();
to ask the user again you should know that there could be characters left in the stdin that need to be read so you can flush them with getchar() so a complete function would be
int scanint(const char *const message)
{
int value;
printf("%s > ", message);
while (scanf("%d", &value) != 1)
{
int chr;
printf("\tinvalid input...\n");
do {
chr = getchar();
} while ((chr != EOF) && (chr != '\n'));
printf("%s > ", message);
}
return value;
}
and you can use it like this
int main()
{
int value = scanint("please input an integer");
printf("your input was: %d\n", value);
return 0;
}
I can give you two approaches:
very easy — check for return value of scanf(). 1 indicates success (integer read) and 0 if any non-integer is put in there (or EOF on EOF).
by writing code for it:
#include <ctype.h>
#include <stdlib.h>
int isNumeric (const char * s)
{
if (s == NULL || *s == '\0' || isspace(*s))
return 0;
char * p;
strtod (s, &p);
return *p == '\0';
}
Now in this case your scanf has to take a string from user and then pass that string to the function isNumeric().

C Determine if user input is an integer

Hi I need to prompt a user for some input and then validate it. The input must only be validated if it is a positive integer and not greater then 23. The only problem I am having with this is when the user enters a non-numerical input like "hello." The code below does not successfully detect that any input is non-numerical and though I have tried many methods to do this, none of them seem to work. Below is the closest I seem to have gotten by taking the input as a string then converting it to an integer, however it still does not work. Any help would be appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void) {
int height;
char input[50];
int cont = 0;
while (cont == 0) {
printf("Please provide a non-negative integer no greater than 23.\n");
scanf("%s", &input);
height = atoi(input);
if (height <= 23 && height >= 0) {
cont = 1;
} else {
//do nothing
}
}
printf("Valid Input.\n");
return 0;
}
The atoi() function has no provision for returning an error indicator. Instead, you can use the strtol() function:
char *end;
height = strtol(input, &end, 10);
if (end == input) {
// no digits were entered
puts("Invalid input.");
continue;
}
#include <stdio.h>
int main(void) {
int height;
while(1){
printf("Please provide a non-negative integer no greater than 23.\n");
//if(2==scanf("%d%c", &height, &nl) && nl == '\n' && 0<= height && height <= 23)//more limited for "number\n"
if(1==scanf("%d", &height) && 0<= height && height <= 23)
break;
//Clear of invalid input
while(getchar()!='\n')
;
}
printf("Valid Input(%d).\n", height);
return 0;
}
I am assuming that you have to consider the whole input into the consideration rather than only certain parts like "12jjj" and "23h" as invalid.
In my opinion, since 23 is only 2 char, so there is no harm in checking the length of the string and the individual characters.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
bool ValidateInput (char * input, int &output)
{
if (strlen(input) > 2)
return false;
for (int index = 0; index < strlen (input); index++)
{
if ((input[index] < '0') || input[index] > '9')
return false;
}
output = atoi(input);
return true;
}
int main(void) {
int height;
char input[50];
int cont = 0;
while (cont == 0) {
printf("Please provide a non-negative integer no greater than 23.\n");
scanf("%s", input);
if (ValidateInput (input, height))
break;
}
printf("Valid Input.\n");
return 0;
}
I hope this helps.

Input several numbers from array and each one number check for integer or not

everyone!
I hope someone can help me figure out something in C language.
This is my first seriously homework in IT, I have no experience and I'm learning in e-studies, so teacher help isn't very available.
I need to develop console application in C language. User need to input 10 integer numbers, if insert number isn't integer, need to output error and again re-enter new number until all 10 integer numbers will be inserted.
Everything works in case if I say that these 10 numbers can't be 0 (I make this to be sure that my if-else statement working), but won't work when I want that every input number will be check if it is integer or not.
How can I do it right.
Please help
so far my code look like this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
float f;
int numbers[10];
for (i = 0; i < 10; i++)
{
scanf ("%d", &numbers[i]);
if (numbers[i] != 0)
{
scanf ("*%d", &numbers[i]);
}
else
{
printf ("\nError!Entered number is't integer \n");
printf ("\nPlease insert number again \n");
scanf("%*d", &numbers[i]);
}
}
}
#include <stdio.h>
int main(void) {
int i = 0;
int val;
char ch;
int numbers[10];
while(i < 10) {
val = scanf("%d", numbers + i); // read the integer into a[i]
if(val != 1) {
while((ch = getchar()) != '\n') // discard the invalid input
; // the null statement
printf("Error! Entered number is not an integer.\n");
printf("Please enter an integer again.\n");
val = scanf("%d", numbers + i);
continue;
}
++i;
}
// process the numbers array
return 0;
}
I write this line again
val = scanf("%d", numbers + i);
Now it works how I need. Great - thanks a lot
There are several techniques you might use:
Read the number as a string and reject if it contains characters not suitable for an integer. The use sscanf() to convert the string to integer.
Read the number as a float and reject if it is out of integer range or it has a non-integer value.
Read the input character by character and build up an integer value. If invalid characters appear, reject the value.
scanf returns the number of input items successfully matched and assigned. You can check this value for 1 for each call of scanf. If the value is 0, then you should discard the input to clear the stdin buffer and read input again.
#include <stdio.h>
#include <ctype.h>
int main(void) {
int i = 0;
int val;
char ch;
int numbers[10];
while(i < 10) {
// read an integer and the first non-numeric character
val = scanf("%d%c", numbers + i, &ch);
// if the number of items assigned by scanf is not 2 or if
// the first non-numeric character is not a whitespace, then
// discard the input and call read input again.
// for example input of type 32ws are completely discarded
if(val != 2 || !isspace(ch)) {
while((ch = getchar()) != '\n') // discard the invalid input
; // the null statement
printf("Error! Entered number is not an integer.\n");
printf("Please enter an integer again.\n");
continue;
}
++i;
}
// process the numbers array
return 0;
}
Although I am not entirely clear on the details of your question, here is an outline of code similar to what you want:
int main(void)
{
int i;
int numbers[10];
int sum = 0;
for(i=0; i<10; ++i)
{
printf("Enter #%d:\n", i+1);
scanf("%d", numbers+i);
if (numbers[i] % 2 == 0) // Then Number is even
{
sum += numbers[i];
}
}
printf("The sum of only the even numbers is %d\n", sum);
getch();
return 0;
}
To read an int, suggest fgets() then sscanf() or strtol()
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i;
int numbers[10];
for (i = 0; i < 10; ) {
char buffer[50];
if (fgets(buffer, sizeof buffer, stdin) == NULL) break;
int n; // number of `char` parsed
if (sscanf(buffer, "%d %n", &numbers[i], &n) != 1 || buffer[n] != '\0') {
printf("Error! Entered number is not an integer.\n");
printf("Please enter an integer again.\n");
continue;
}
i++;
}
return 0;
}
The strtol() approach. This detects overflow issues:
if (fgets(buffer, sizeof buffer, stdin) == NULL) break;
char *endptr;
errno = 0;
long num = strtol(buffer, &endptr, 10);
if (errno || num < INT_MIN || num > INT_MAX) Handle_RangeError();
if (buffer == endptr || *endptr != '\n') Handle_SyntaxError();
numbers[i] = (int) num;
Recommend making a int GetInt(const char *prompt) function that can be used repeatedly.
User input is evil. Do not trust it until well vetted.

Resources