Numeric input validation in C - c

I am doing a lab for an intro programming class
I have to make sure that an integer is entered. I thought this would do it but when I put in a letter it repeats in an endless loop.
I found this solution in another post
int num;
char term;
if (scanf("%d%c", &num, &term) != 2 || term != '\n')
printf("failure\n");
else
printf("valid integer followed by enter key\n");
But im not sure what I did wrong. Why is it not working in my code?
#include <stdio.h>
int main(void)
{
int oneVar;
char term;
double numOne;
double numTwo;
double sum;
double dif;
double quo;
double mult;
int checker = 1;
do
{
printf("Please choose one of the following:\n""1) Add\n""2) Subtract\n""3) Divide\n""4) Multiply\n""5) Quit\n");
if (scanf("%d%c" , &oneVar ,&term) != 2 || term != '\n')
{
printf ("This is not valid input\n\n");
checker = 1;
}
else if (oneVar == 5)
{
printf("Thank you. Goodbye.\n");
checker = 0;
}
else if (oneVar != 1 && oneVar !=2 && oneVar != 3 && oneVar != 4)
{
printf("This is not a valid input\n\n");
checker = 1;
}
else
{
printf("Please enter the first number:\n");
if (scanf("%lf%c" , &numOne ,&term) != 2 || term != '\n')
{
printf ("This is not valid input\n\n");
checker = 1;
}
printf("Please enter the second number:\n");
if (scanf("%lf%c" , &numTwo ,&term) != 2 || term != '\n')
{
printf ("This is not valid input\n\n");
checker = 1;
}
else if (oneVar == 1)
{
sum = numOne + numTwo;
printf("The sum is: %.2lf\n" ,sum);
checker = 0;
}
else if (oneVar == 2)
{
dif = numOne - numTwo;
printf("The difference is: %.2lf\n" ,dif);
checker = 0;
}
else if (oneVar == 3)
{
quo = numOne / numTwo;
printf("The quotient is: %.2lf\n" ,quo);
checker = 0;
}
else if (oneVar == 4)
{
mult = numOne * numTwo;
printf("The product is: %.2lf\n" ,mult);
checker = 0;
}
else if (oneVar == 5)
{
printf("Thank you. Goodbye.\n");
checker = 0;
}
}
} while (checker == 1);
return(0);
}
My prof posted this Im not sure how it helps but I thought it might help someone
To make sure that a user-input number is an integer you can use the notion of casting. Casting is a way to tell C to treat a variable as if it were a variable of a different type.
so, if I have something like this:
double myDouble;
myDouble = 5.43;
printf ("%d", (int) myDouble);
It will tell C to print myDouble, but to treat it like an integer. Only the 5 will be printed and you won't get any type mismatch errors. You can use casting to check to see if an input number is an integer by comparing the input to the (int) cast of the number. Something like this should work:
if(inputNum == (int) inputNum)
You'll still get 1.0 and 2.0 passing as valid numbers, but that is ok for now.

Why complicate things?
char x = 0;
scanf("%c", &x);
if (x >= 0x41 && x <= 0x7A)
printf("you entered a letter");
In ASCII table, letters have values between 0x41 ("A") and 0x7A ("z").
So, you just need to check the ASCII value of the input. :)

Using the %c to "consume" the end of line is not a good solution. If the user enters say:
123 abc<newline>
num will be 123, but term will be the space character. If you enter a letter rather than a number, the scan will stop without consuming any of the characters, the next input call will return due to the already buffered line, and may still consume nothing. Your program loops continuously because every input statement is failing to consume the newline and returns immediately. The standard input functions wait for a complete line before returning, if the line is not read completely, input functions do not need to wait.
There are a number of solutions, many of which such as the one you used are flawed, the method below, forces the input buffer to be flushed up to and including the newline.
int check = scanf( "%d", &num ) ;
while( getchar() != '\n' )
{
// do nothing
}
if( check != 2 )
printf("failure\n");
else
printf("valid integer followed by enter key\n");
If you use the %c format specifier at the end of the input, then a slightly different flush is necessary since the character input may be a newline:
int check = scanf( "%c", &ch ) ;
while( ch != '\n' && getchar() != '\n' )
{
// do nothing
}

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

Validating user input between 1-9 using getchar()

Hey guys im trying to write a small program where the user has to put in a number between 1-9, anything else is an error, but I'm having trouble validating the input because if you put 12 it only reads the 1 and it goes in the loop. It has to be done using getchar() this is what have so far:
printf(%s,"please enter a number between 1 - 9);
int c;
c = getchar();
while(c != '\n') {
int count = 1;
count ++;
if ((c >= '0' && c <= '9') || count > 1) {
printf(%s, "Congrats!);
}
else
{
print(%s, "ERROR);
}
}
I'm also having problems validating the char into an int after it goes in. If i put in 5 i get 53.
Try changing count > 1 to count == 1, and initialize it to 0 rather than 1. That way you can keep count of the number of digits you have. Also, note that because you initialize count to 1 and then immediately increment it, count > 1 will always evaluate to true, so if you gave it any char it will always say it's correct.
getchar() will return the next character typed. If you want more than the first character you will need a call getchar() again within the while loop.
//Somewhere to store the result
//initialized with an invalid result value
int digitchar = 0;
//Get the first char
int c = getchar();
while (c != '\n')
{
//Check if we already have a digit
//and that the new char is a digit
if (digitchar == 0 && c >= '1' && c <= '9')
{
digitchar = c;
}
//Get the next char
c = getchar();
}
//Check if we have stored a result
if (digitchar != 0)
{
//Success
}
Note this doesn't handle if a non-digit or newline character is entered. You would need to handle that as an error as well as if more than one digit is entered.
This is not working with 12 because getchar() takes one character per time.The following example is one way to solve it.
printf("please enter a number between 1 - 9");
int c[10], count=1;
//Declare an array because user may insert a bigger number
char number;
//This loop allow the user to enter an input
for(i=0;i<10;i++){
number = getchar();
if (number != ' '){
c[i] = atoi(number);
sum = sum + c[i];
}
else if(number == ' '){
//Terminate the loop when user stop typing
break;
}
else if( sum > 9 || sum < 0){
//Start loop again until user enter valid input
printf("You entered a number out of field try again\n");
continue;
}
}
while(c != '\n') {
count ++;
if ((c >= '0' && c <= '9') || count > 1) {
printf("%d Congrats!",c);
}
else
{
printf(" %d ERROR", c);
}
}
Remember that getchar() returns the ascii value of the char, thus when you pass the value to the function you must subtract char '0' to pass the actual decimal value into the function.
Another point is that you must clear the input buffer. If your user enters wrong input, you have to make sure that there is nothing left on the input buffer before you try to read input again.
Hope this helps.
int main(void) {
int input = 0; // 0 is the sentinel value to close program
printf("\n%s\n", "Enter value between 1-9 .\nEnter [0] to finish.");
do {
input = getchar();
if (((input>= '1') && (input <= '9') || input == '0') && getchar() == '\n') {
if ((input >= '1') && (input <= '9')) {
callYourOwnFuntionAndPassValue(input - '0');
printf("\n%s\n", "Enter value between 1-9 .\nEnter [0] to finish.");
}
}
else {
while (getchar() != '\n') {} // clear input buffer
printf("\n%s\n", "Please enter a valid number");
}
} while (input != END_PROGRAM);
return NO_ERROR; // NO_ERROR = 0
}

Difficulty using scanf for input

Can someone help me to solve my problem? I have a problem with %[^\n]. When I try to enter a false input the program loop the warning that I wrote, but if I use %s and I enter my string the next statement is not working properly.
#pragma warning (disable:4996)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
char name[30];
char number[12];
int flag, flag1, flag2, flag3;
int i;
printf("Add New Contact\n");
do {
printf("input name [1..30 char]: ");
scanf("%[^\n]", name); fflush(stdin);
if ((name[0] >= 'A' && name[0] <= 'Z') || (name[0] >= 'a' && name[0] <= 'z')) {
flag = 1;
}
else {
flag = 0;
printf("First letter of name should be an alphabet (A-Z or a-z)\n");
}
if (strlen(name) > 30) {
flag1 = 0;
printf("Length of name should be between 1 and 30 characters\n");
}
else {
flag1 = 1;
}
} while (flag == 0 || flag1 == 0);
do {
printf("Input phone number[6..12 digits]: ");
scanf("%s", number); fflush(stdin);
for (i = 0; i < strlen(number); i++) {
if (number[i] >= '0' && number[i] <= '9') {
flag2 = 1;
}
else {
flag2 = 0;
}
}
if (flag2 == 0) {
printf("Phone numbers should only contain digits (0-9)\n");
}
if (strlen(number) >= 6 && strlen(number) <= 12) {
flag3 = 1;
}
else {
flag3 = 0;
printf("Length of phone numbers should be between 6 and 12 digits\n");
}
} while (flag2 == 0 || flag3 == 0);
printf("\n");
printf("New contact successfully added!\n");
printf("Press Enter to continue...");
getchar();
getchar();
return 0;
}
Oh by the way, the problem might simply be that the scanf call leaves the newline in the buffer, and if you loop and try again the first character seen will be the newline and scanf should not read any thing.
There are two things you should do: First check what scanf returns, it should return 1 if it read a string. Secondly you should tell scanf to discard any possible leading white-space by adding a space first in the format string: " %[^\n]".
Most scanf formats automatically skips leading white-space, but not when using the "%[" or "%c" formats.
Also, to not worry about writing out of bounds of the array, you should add a length modifier to make sure that scanf doesn't read more input than it can write: " %29[^\n]". If the length of the string is 29 after this, then you should probably read until you reach the end of the line, character by character.
Here is your program fixed:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
// In case you need this -- not needed for this case
void discard_input()
{
char c;
while( ( c = getchar() ) != '\n' && c != EOF );
}
void remove_trailing_newline(char * s)
{
char * ch = s + strlen( s ) - 1;
while( ch != s ) {
if ( *ch == '\n' ) {
*ch = 0;
break;
}
--ch;
}
return;
}
int main(){
char name[30];
char number[12];
int flag, flag1, flag2, flag3;
int i;
printf("Add New Contact\n");
do {
printf("\nInput name [1..30 char]: ");
fgets( name, 30, stdin );
remove_trailing_newline( name );
flag1 = flag = 1;
if ( !isalpha( name[ 0 ] ) ) {
flag = 0;
printf("First letter of name should be an alphabet (A-Z or a-z), found: %s\n", name );
}
// impossible
if (strlen(name) > 30) {
flag1 = 0;
printf("Length of name should be between 1 and 30 characters\n");
}
} while (flag == 0 || flag1 == 0);
do {
printf("\nInput phone number[6..12 digits]: ");
fgets( number, 12, stdin );
remove_trailing_newline( number );
flag2 = flag3 = 1;
int len_phone = strlen( number );
for (i = 0; i < strlen(number); i++) {
if ( !isdigit( number[ i ] ) ) {
flag2 = 0;
}
}
if (flag2 == 0) {
printf("Phone numbers should only contain digits (0-9), found:'%s'\n", number);
}
if ( len_phone < 6 || len_phone > 12) {
flag3 = 0;
printf("Length of phone numbers should be between 6 and 12 digits, found: %d\n", len_phone );
}
} while (flag2 == 0 || flag3 == 0);
printf("\n");
printf( "Name: '%s'\n", name );
printf( "Phone: '%s'\n", number );
printf("New contact successfully added!\n");
printf("Press Enter to continue...");
getchar();
return 0;
}
You can find the program here.
The fixings are more or less interesting, I enumerate they here:
At first, I thought that the problem was that the trailing new line was being left in the input buffer. fflush(stdin) is actually undefined behaviour in C, since the fflush() function is there for output streams. Anyway, I included the code in question 12.26b of the comp.lang.c FAQ, since I think it is interesing to have it as reference. Then, I decided to change scanf() with fgets(). This is due to the scanf() taking spaces as delimiters, so you wouldn't be able to write a complete name, i.e., name and surname. Remember that gets() is not an option, since it writes the input past the limit of the buffer. Actually, fgets() solves this by letting us define a limit of chars to read. The problem is that fgets() also includes the '\n' in the buffer, so, that's why I included the remove_trailing_newline() function. Tricky, isn't it?
You added a condition to check whether the name input had more than thirty chars. Actually, this is impossible to check in your program. First of all, fgets() will read 29 chars + the final char mark (0). Secondly, if you were actually allowing to input more than 30 chars, then the input would be written past the size of the buffer, which is undefined behaviour (crashes in most cases). You would have to use something more complex, like std::string in C++, and then check its length. Or maybe use a third party expandable string for C. Or roll out your own expandable string...
You can decide whether there is an alphabetic char or a digit by using isalpha(c) and isdigit(c) functions.
When you are going to use a value many times, such as strlen(name), then you should precompute it and store it in a local variable. Though a good compiler (its optimizer) will detect this situation and solve it for you, you never know which compiler is going to compile your code, and how advanced it is. Also, there is nothing wrong making things easier for the optimizer.
When you have a situation in which you set a flag for signaling an error condition, it is easier to set it to the "no error" value before checking anything, and solely in case of an error, set it to the "error" value. This will be easier to read, and therefore, to understand.
Hope this helps.

C user input only integers, return value from scanf

I am trying to get some user input, and I want to make sure that they enter integers, and if they don't I will just ask them to type again (loop until they get it right).
I have found a lot of different approaches to do this; some more complicated then others. But I found this approach which seems to work.
But I just don't really get why this is tested in the code:
scanf("%d%c", &num, &term) != 2
I can understand that scanf outputs the number of items successfully matched and assigned, but I don't get why it outputs 2 if it is an integer.
The code in C is:
int main(void)
{
int num;
char term;
if (scanf("%d%c", &num, &term) != 2 || term != '\n')
printf("failure\n");
else
printf("valid integer followed by enter key\n");
}
Trying to put it in loop:
int main(void){
int m, n, dis;
char m_check, n_check, dis_check;
do{
m = 0; n = 0; dis = 0;
m_check = ' '; n_check = ' '; dis_check = ' ';
printf("Please enter number of rows m in the matrix (integer): ");
if(scanf("%d%c", &m, &m_check) !=2 || m_check != '\n')
m_check = 'F';
printf("Please enter number of columns n in the matrix (integer): ");
if(scanf("%d%c", &n, &n_check) !=2 || n_check != '\n')
n_check = 'F';
printf("Should the random numbers come from a uniform or normal distribution?...
Please press 1 for uniform or 2 for normal: ");
if(scanf("%d%c", &dis, &dis_check) !=2 || dis_check != '\n' || dis != 1 || dis !=2)
dis_check = 'F';
}while(m_check == 'F' || n_check == 'F' || dis_check == 'F');
I've tried just inputting m = 3, n = 3, dis = 2, and then the loop just starts over and asks me to input number of rows. And if I when asked for this press f or something it just start looping like crazy over the printf-statements :)
scanf returns the number of fields it converted. You have the format string %d%c; it has:
%d - first field
%c - second field
so scanf returns 2.
If the user enters a number e.g. 123 and presses Enter, your num will be equal to 123, and term will be \n.
If the user enters a number with garbage at the end, e.g. 123garbage and presses Enter, your num will be equal to 123, the term will be g, and arbage\n will remain in the input buffer.
In both cases, scanf read an int and a char, so it returns 2.
A different example: the user enters garbage123. In this case, scanf will fail to read an integer, and return 0.
So your code checks for two different forms of incorrect output.
Entering an integer will match to the formatter %d and will assign the value to the variable num. The %c formatter will take the newline character ('\n') and store it in the variable term. scanf returns 2 cause 2 elements where correctly assigned (num and term)
If you don't enter an integer the formatter %d won't match correctly, and scanf won't return 2, producing a failure
Edit: Your do-while loop goes crazy cause your conditions in the last scanf are wrong (dis != 1 || dis !=2). It should be
if(scanf("%d%c", &dis, &dis_check) !=2 || dis_check != '\n' || (dis != 1 && dis !=2))
scanf("%d%c", &num, &term) != 2
This checks the return value of scanf . It will return number of arguments correctly matched . So , if a integer and a character is entered , they are store in vairables num and term and scanf returns 2 .
scanf will not return 2 if both the arguments are not correctly matched , in that case failure will be displayed as output.
Oops - now see OP wants to know why approached failed and was not necessarily looking for a how-to do it. Leaving this up as a reference as it does assert the fundamental problem: scanf(). Do not use it for user input.
If code truly needs to "get some user input, and wants to make sure that they enter integers", then use fgets() to get the line and then process the input.
Mixing user input with scanning/parse invariably results in some user input defeating the check, extra user input in stdin or improperly waiting for more input.
// true implies success
bool Read_int(int *value) {
char buffer[100];
if (fgets(buffer, sizeof buffer, stdin) == NULL) return false; // EOF or error
// Now parse the input
char *endptr;
errno = 0;
long number = strtol(buffer, &endptr, 10);
if (errno) return false; // long overflow
if (number < INT_MIN || number > INT_MAX) return false; // int overflow
if (endptr == buffer) return false; // No conversion
while (isspace((unsigned char) *endptr)) endptr++;
if (*endptr) return false; // non-white-space after number
*value = (int) number;
return true;
}

A basic/ manual way to check that a value entered by the user is numeric

I've searched in and out of these forums but am still having trouble. My understanding of C is still very basic. I'm creating a small program that takes 3 numerical values entered by the user and then calculates the highest. I nailed that.
I now want to ensure that the user enters only integer values. I managed to get the prog to keep prompting the user to re-enter the value until it is within the specified numerical range (for example, any number between 1 and 1000 inclusive, piece of cake) but that's not good enough. I used 3 while loops to test each value, but this only works as long as the input is of type integer.
The trick is I cant use built in functions. It needs to be manual (sorry, poor choice of words) I tried to use char variables and x = getchar(); to get the ASCII value and test it in a condition but I can't get it working in a loop. (while/ do-while)
I also tried using a "for loop" and array variables but once again am struggling to get it to keep prompting the user.
I've also tried to test the value returned by scanf to see if its integer but my knowledge level of correct C syntax is level: noob. Either my loops don't loop or they loop infinitely.
Here is some sample code:
int x, y, z =0;
printf("Enter the first number:\n");
scanf("d", &x);
while (condition) /* Here is where I need to determine that the entered val is false */
{
printf("Wrong input. Re-enter a valid value.\n");
x =0;
scanf("%d", &x); /*user re-prompted */
}
I'm getting the idea that I'll have to use ASCII and a loop, but I just can't get to it. Also, the values entered get sent to a function for comparing and are then returned.
Could someone give me some advice and a few tips please?
Much thanks
You would have to use something like fgets, and strtol:
long someValue;
char *bufEnd = NULL;
char buf[128]; // max line size
do {
printf("enter a value: ");
fgets(buf, 128, stdin);
someValue = strtol(buf, &bufEnd, 10); // base 10
} while (bufEnd == buf || *bufEnd != '\n');
printf("got value: %li", someValue);
What we are doing here is we are tapping into strtol's capability to tell us where it stopped parsing, by passing in bufEnd.
Then, we are making sure that bufEnd doesn't point to the beginning of buf (in which case, it didn't start with a number), and also checking to make sure that bufEnd points to \n, or the end of the line (making sure that the user didn't enter something like 123abc, which strtol would interpret as 123). You may wish to trim buf of whitespace characters first, however.
You're absolutely on the right track with "scanf()". Just check the return value. If you don't get the expected #/values, then you got invalid input:
char found = FALSE;
int ival;
double x;
while (!found)
{
printf("Please enter a valid integer: ");
if (scanf("%d", &ival) !=1) {
printf ("Invalid! Please re-enter!\n");
continue;
}
printf("Please enter a valid floating point number: ");
if (scanf("%lf", &x) !=1) {
printf ("Invalid! Please re-enter!\n");
continue;
}
found = TRUE;
}
Here's my solution. It safe against buffer overflow and straightforward .
#include <stdio.h>
#define LEN 10
int main() {
int a;
char str[LEN];
fgets( str, LEN, stdin );
while ( !sscanf( str, "%d", &a ) )
fgets( str, 10, stdin );
printf("Num is : %d\n", a);
return 0;
}
#include <stdio.h>
#include <limits.h>
#include <ctype.h>
int getInteger(int* err){
int ch;
int n;//int32
int takeNum, sign;
long long int wk;//long long int as int64
wk=0LL;
*err = 0;
takeNum = 0;//flag
sign = 1;//minus:-1, other:1
/* //skip space character
while(EOF!=(ch=getchar()) && (ch == ' ' || ch == '\t' || ch == '\n'));
ungetc(ch, stdin);
*/
while(EOF!=(ch=getchar())){
if(ch == '-'){
if(takeNum != 0){//in input number
*err = 1;
break;
}
if(sign == -1){//already sign
*err = 2;
break;
}
sign = -1;
continue;
}
if(ch >= '0' && ch <= '9'){//isdigit(ch) in ctype.h
if(takeNum == 0)
takeNum = 1;
wk = wk * 10 + (ch - '0')*sign;
if(INT_MAX < wk || INT_MIN > wk){//overflow
*err = 3;
break;
}
continue;
}
if(ch != '\n'){//input other [-0-9]
*err = 4;
}
break;
}
if(takeNum == 0){//not input number
*err = 5;
} else {
n=wk;
}
while(ch != '\n' && EOF!=(ch=getchar()));//skip to newline
return n;
}
int getValue(const char* redoprompt, int low, int high){
int num, err=0;
while(1){
num = getInteger(&err);
if(err || low > num || high < num)
printf("%s", redoprompt);
else
break;
}
return num;
}
#define max(x,y) ((x)>(y))? (x) : (y)
int main(){
const char *error_message = "Wrong input. Re-enter a valid value.\n";
int x, y, z, max;
x = getValue(error_message, 1, 1000);
y = getValue(error_message, 1, 1000);
z = getValue(error_message, 1, 1000);
max = max(max(x,y), z);
printf("max:%d\n", max);
return 0;
}

Resources