Programming in C. Error Handling an integer value - c

I have an integer input for my I.D. My teacher says I need to error handle all my inputs and basically display appropriate error messages if input entered is invalid. So I'm trying to get an error message to pop up if the user enters a real number or number less than one. But what I've tried is not working!
printf("Enter client Id--->");
scanf("%d", &client.id);
while ((client.id < 1) || (client.id % 1 != 0)) {
printf("Invalid I.d entered\n");
printf("Enter client Id--->");
scanf("%d", &client.id);
} // endwhile`

scanf("%d", &client.id);
You have to test the return value of scanf. If the result is 1, it has successfully scanned your integer. All you have to do next is to test that the value is >=1.
So, something like that:
while( 1 ) {
printf("Enter client Id--->");
int scanned = scanf("%d", &client.id);
if( scanned != 1 || client.id < 1 ) {
// note: infinite loop for invalid input, see note below
printf("Invalid I.d entered\n");
}
else {
break; // OK
}
}
NB(1) see there for a an explanation of why scanf is unsafe and ways of making it safe(r).
NB(2) you haven't included the client.id declaration, but it has to be an int type. Even if you wanted to scan a float instead of an int, x % 1 != 0 is a no-no.

You can add a printf after the scanf to ensure scanf is working as expected.
Still, regardless of what value is entered, the program exits without entering while() body.
Of the two while() conditions, the first is innocuous, but the second is suspect because it is false for all values.

To check that a number is not an integer, the easiest way (the way without function calls) would be client.id != (int)client.id.
But first, you must read the number as a floating-point type, precisely so you can catch that error. My code:
double x;
printf("Enter client Id--->");
scanf("%lf", &x);
while((x < 1.0) || (x != (int)x))
{
printf("Invalid I.d entered\n");
printf("Enter client Id--->");
scanf("%lf",&x);
} // endwhile
client.id = (int)x;

Related

multiply numbers untill the user enters 0

I don't know why but the loop doesn't stop even when I enter 0. can someone help me with this?
int main(void)
{
float number,product = 1;
printf("Provide floats separated by a line: \n");
scanf("%f" , &number);
while(number != 0)
{
product *= number;
if(number == 0)
break;
}
printf("The product of your values is: %.2f" , product);
printf("\n");
}
You'll need to place the scanf call inside the loop to repeatedly ask the user for input. As it is you only ask once, and then loop forever on the same value.
Here we place the call in the predicate itself:
#include <stdio.h>
int main(void) {
float number = 0,
product = 1;
puts("Provide floats separated by a line:");
while (scanf("%f" , &number) == 1 && number)
product *= number;
printf("The product of your values is: %.2f\n" , product);
}
You should always check the return values of your I/O functions. scanf returns the number of conversions that took place, which here should be 1. On error, EOF, or number being 0 we do not continue the loop.

Verifying inputs and repeating statements

I need to take two numbers from two separate scans and find the GCD of both of them. I have this currently which will take the two numbers, but I need to validate input with a function. It should work as follows, I enter a number and it checks to verify that it is a positive integer. If not it should prompt me to say that the input is unrecognized and ask for it again. Once I input a valid number, it should continue to ask me to put in a second one and do the same verification process. Any help with input validation and repeating the question in a function would be helpful.
int main()
{
int num1, num2, i, GCD;
printf("Please enter a positive integer: \n");
scanf("%d" ,&num1);
printf("Please enter a positive integer:\n");
scanf("%d", &num2);
if (num1 >0 && num2 > 0) {
for(i = 1; i <= num1 && i <= num2; i++)
{
if(num1 % i == 0 && num2 % i == 0)
GCD = i;
}
}
else {
printf("I'm sorry that number is unrecognized or negative.\n");
}
printf("The largest integer that divides both %d and %d is: %d\n",num1,num2, GCD);
return 0;
}
you can use a do-while loop and put your scanf in there as long as you dont get a valid answer. For example:
do {
// put your scans here
} while(num1<0 || num2<0);
Also you can catch the case if he inputs a character instead of integer input! So that is a good way to repeat a prompt until you get the valid answer.

If statement inside while loop with the same condition

Is there a better way to write the following code by eliminating the repeated condition in the if statement in C?
while (n < 0) {
printf("Enter a positive integer: ");
scanf("%d", &n);
if (n < 0) {
printf("Error: please enter a positive integer\n");
}
}
Thank you.
Simply rework your loop breaking when correct input is given. This way the check is done only one time:
while (1)
{
printf("Enter a positive integer: ");
scanf("%d", &n);
if (n >= 0)
break;
printf("Error: please enter a positive integer\n");
}
And, as specified in comments, an optimized compiler should be able to reverse the loop by itself.
This is something that IMO is best accomplished with a bit of refactoring:
#include <stdio.h>
#include <stdbool.h>
static bool get_postive_integer(int *pOut) {
int n;
printf("Enter a positive integer: ");
scanf("%d", &n);
if(n < 0)
return false;
*pOut = n;
return true;
}
int main(void)
{
int n;
while (!get_postive_integer(&n)) {
printf("Error: please enter a positive integer\n");
}
}
Give the operation a name, check that it fails, and only then print a message accordingly. The success or failure condition is only coded once here, in the named operation.
You could use:
while (printf("Enter a positive integer: ") > 0 &&
scanf("%d", &n) == 1 &&
n < 0)
{
printf("Error: please enter a positive integer\n");
}
This stops if the printf() fails, if the scanf() fails, or if the value in n is non-negative. It's a good idea to always check that the scanf() succeeds. It is merely convenient that printf() returns the number of characters it wrote (or a negative number on failure) so it can be used in a condition too. You could add fflush(stdout) == 0 && into the stack of operations too.
Or you could decide that the code in the condition should be in a function:
static int read_positive_integer(void)
{
int value;
if (printf("Enter a positive integer: ") > 0 &&
fflush(stdout) == 0 &&
scanf("%d", &value) == 1 &&
value >= 0)
return value;
return -1;
}
and then the calling code is:
while ((n = read_positive_integer()) < 0)
printf("Error: please enter a positive integer\n");
There are many variations on the theme; you might wrap the while loop into a function; you might make the prompts into parameters to the function. You might decide to be more careful about reporting what goes wrong (different actions if printf() fails compared with what happens if scanf() returns 0 (non-numeric data in the input) or EOF (no more data in the input).
The following examples are presented in the spirit that people should know what is available in the language.1 The way I would usually write the code is shown in Frankie_C’s answer. As some have noted, optimization usually makes this simple case not worth worrying about, but the question is not limited to a simple evaluation like n < 0; the test might be a function call to some expensive evaluation of more complicated criteria.
Folks are not going to like this, but:
goto middle;
do
{
printf("Error, please enter a positive integer\n");
middle:
printf("Enter a positive integer: ");
scanf("%d", &n);
} while (n < 0);
If you are vehemently opposed to goto, you can use a stripped-down version of Duff’s device:
switch (0)
do
{
printf("Error, please enter a positive integer\n");
case 0:
printf("Enter a positive integer: ");
scanf("%d", &n);
} while (n < 0);
But you should not.
Footnote
1 Commonly, software engineers will have to work with code written by others, so they must be prepared to recognize and understand anything expressible in the language, even if that is just a first step toward rewriting it into better code. And occasionally situations arise where “ugly” code becomes desirable for commercial or other practical reasons.
Another alternative is to split into a function:
int func(){
int n;
printf("Enter a positive integer: ");
scanf("%d", &n);
return scanf("%d", &n) == 1 ? n : -1;
}
and the loop becomes
while ((n = func()) < 0){
printf("Error: please enter a positive integer\n");
}
although the assignment in the condition check is not to everyone's taste. Note that I return -1 if the return value of scanf is not 1, something that you should always check.
What I do though in this situation (See Eric's answer) is to write
switch (0) do {
printf("Error, please enter a positive integer\n");
case 0:
printf("Enter a positive integer: ");
scanf("%d", &n);
} while (n/*ToDo - make sure n is initialised if scanf fails*/ < 0);

Why doesn't isdigit() work?

I'm trying to make a program that generates a random number, asks the user to guess and then responds whether or not he got it right. For some reason, regardless of wether the user puts in a digit or not, it responds as if he didn't. Any ideas? thanks for helping out a beginner :)
#include<stdio.h>
#include<ctype.h>
#include<time.h>
main()
{
char iRandomNum = '\0';
int iResponse = 0;
srand(time(NULL));
iRandomNum = (rand() % 10) + 1;
printf("Guess the number between 1 yand 10 : ");
scanf("%d", &iResponse);
if (isdigit(iResponse) == 0)
printf("you did not choose a number\n");
else if (iResponse == iRandomNum)
printf("you guessed correctly\n");
else
printf("you were wrong the number was %c", iRandomNum);
}
isdigit() takes the ascii value of a character and returns 0 if it's not a digit and non-0 if it is.
You are passing to it an integer value which is not necessarily an ascii value, you don't need to check if it's a digit since you read it with scanf().
If you want to make sure scanf() did read a number, check the return value of scanf() instead.
Try this
if (scanf("%d", &iResponse) != 1)
printf("you did not choose a number\n");
instead of the if (isdigit( ...
One more thing, main() must return int.

C. Printing error messages due to user entering letter instead of number

The user has to enter a number greater than 0 in order to print some stuff.
my code for when the user enters a number less than 0 uses a while loop. It then asks the user to type in a number again.
while(x<=0){
print("Must enter a number greater than 0");
printf("Enter a number: ");
scanf("%i",&x);}
How can I create an error message formatted similarly to the one above, but for a user who enters a "x" or a word. Thanks
Since the reading is done using scanf with a numeric format, it means that if you enter something that can't be read as an integer (123) or part of an integer (123x is ok, the parsing stops soon after the 3), the scanf fails (i.e. it can't parse the input as number). Scanf returns the number of successfully parsed items. So you expect 1 in your case. You can check the return value (if it's 0, scanf wasn't able to get any number from the input) but as said before you still accept thigs like 123x (and the "residual" x will be parsed in the next scanf from stdin, if you do it).
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main(void){
int x;
int ok=0;
do{
char buff[32], *endp;
long long num;
ok = !ok;//start true(OK)
printf("Enter a number: ");
fgets(buff, sizeof(buff), stdin);
x=(int)(num=strtoll(buff, &endp, 0));//0: number literal of C. 10 : decimal number.
if(*endp != '\n'){
if(*endp == '\0'){
printf("Too large!\n");
fflush(stdin);
} else {
printf("Character that can't be interpreted as a number has been entered.\n");
printf("%s", buff);
printf("%*s^\n", (int)(endp - buff), "");
}
ok = !ok;
} else if(num > INT_MAX){
printf("Too large!\n");
ok = !ok;
} else if(x<=0){
printf("Must enter a number greater than 0.\n\n");
ok = !ok;
}
}while(!ok);
printf("your input number is %d.\n", x);
return 0;
}

Resources