Verifying inputs and repeating statements - c

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.

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.

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);

How i cannot ignore 0(zero) as a grade?

int main(){
char students_number[30], students_grade[30];
char *number, *value;
int flag=0, students, i, grade, a=0, b=0, c=0, d=0, f=0;
float sum=0;
while(flag==0) // This while loop exist just because to run program until the number of students will be given correct..
{
printf("Please enter the number of students (It must be between 1-100): ");
scanf("%s",&students_number); // This scanf gets the number of students as an array instead of integer because the number which was given needs to be checked..
students = strtol(students_number, &number, 10); // strtol is a function of stdlib.h and checks the variable is whether int or not for this program..
if(students<=100 && students>0)
{
for(i=1;i<=students;i++)
{
printf("Please enter %d. student's grade (in integer form):",i);
scanf("%s",&students_grade);// This scanf gets the number of students as an array instead of integer because the number which was given needs to be checked..
grade = strtol(students_grade, &value, 10); // This line checks the grade which was given is integer or not by using strtol which is in the stdlib.h..
if(grade<0 || grade>100 || grade=='\0')
{
printf("The grade of the student was given incorrect!\n");
i--; // To make the for loop which is on the 25th line work again until the grade will be given correct..
}
else
{
if(grade<=50 && grade>=0) // This if and else if commands work for to count how many f,d,c,b and a are exist..
f++;
else if(grade<=60 && grade>=51)
d++;
else if(grade<=73 && grade>=61)
c++;
else if(grade<=85 && grade>=74)
b++;
else if(grade<=100 && grade>=86)
a++;
sum += grade;
}
}
sum /= students; // This command divides the sum of the grades to number of the students to get the average results in the class..
printf("\nThe average result of the class is %.2f..\n",sum);
printf("\nThe letter form of the all results are:\nNumber of F: %d\nNumber of D: %d\nNumber of C: %d\nNumber of B: %d\nNumber of A: %d\n",f,d,c,b,a);
flag = 1; // As it was mentioned before, this commands exist to break the while loop because the program was done successfully..
}
else // This if command controls the number of students wheter was given right or not..
{
printf("Please enter a proper number of students.\n");
flag = 0;
}
}
return 0;
}
Hello, this is my first question. I had to create a program which calculates the average of the results. But when i enter 0(zero) as a grade then it doesn't allow it just because i tried to exclude the every types except int type.
How can i make this correct?
You can use scanf to read a number and check that scanf done correctly its work:
from man scanf:
Return Value
These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.
So you can check that you've read an integer with scanf, without writing if (value == '\0'), which prevents you to read 0 grades...
for(i=1;i<=students;i++)
{
int ok;
printf("Please enter %d. student's grade (in integer form):",i);
/* read line from input. Why using fgets instead of scanf directly? See http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html*/
if (NULL == fgets(students_grade, sizeof students_grade, stdin))
{
perror("fgets");
exit(1);
}
/* **try** to parse what have been read */
ok = sscanf(students_grade, "%d", &value);
/* check that scanf has done its work */
if (1 != ok)
{
printf("The grade of the student was given incorrect!\n");
i--; // To make the for loop which is on the 25th line work again until the grade will be given correct..
}
else
{
if(grade<=50 && grade>=0) // This if and else if commands work for to count how many f,d,c,b and a are exist..
f++;
/* ... */
}
I also advice you to read this article: http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html.

Another way to terminate loop?

I'm studying loops in class and for one of the labs, I have to figure out a way for the user to enter an unspecified number of integers to calculate the average. I know I can have the user enter the number of integers to be averaged in order for the loop to be terminated like below:
int count = 0, value = 0, sum = 0, numberofintegers = 0;
double avg = 0;
printf("enter the number of integers you wish to average\n");
scanf("%d",&numberofintegers);
//loop
while (count < numberofintegers)
{
printf("enter a positive integers\n");
scanf("%d",&value);
sum = sum + value;
count = count + 1;
}
avg = (double) sum/count;
So basically I could have a user input the number of integers to be averaged in order for the loop to terminate, but there has to be another way to make the loop terminate without having the user input it?
Normally you'd use a predetermined "illegal" number like (say -1)
input = read_a_value();
while(input != -1)
{
// do something with input
input = read_a_value();
}
scanf returns the number of successful entries.
This may solve your issue.
#include<stdio.h>
int main(void)
{
int number, total = 0, count = 0;
char c;
printf("Enter a number to continue, a character to exit\n");
while (scanf("%d", &number) == 1)
{
total+= number;
count++;
}
/* You need to handle the case where no valid input is entered */
(count > 0) ? printf("Average : %.2f\n", (float)total / count) : printf("No valid numbers entered\n");
/* I have casted the average to float to keep the precision*/
while (getchar() != '\n')
;;
printf("Press any key to continue..");
getchar();
return 0;
}
A downfall is that the scanf will continue to prompt for input if a user presses the Enter Key repeatedly. In fact you might wish to replace the scanf with fgets. Have a look here.
If you are sure that the user doesn't enter too many numbers, use a string.
Length of string, you can choose according to you and split it using spaces to get the numbers

Programming in C. Error Handling an integer value

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;

Resources