So, I am using xcode on mac and made a program that basically does simple math with the users entered values and keeps looping unless it is interrupted. At the end of the loop (once it is broken) I want to print out the total average value (so do some more math). I use a counter and sum variables to do this. However, in out output, I am getting a "nan" error when the loop end and the overall average has to display. Can anyone help, please? :/
int main() {
double gallons=0;
double miles=0;
double sum=0;
int count=0;
while (gallons>=0) {
sum+=(miles/gallons);
count++;
printf("\nEnter the gallons used (-1 to end): ");
scanf("%lf",&gallons);
if (gallons<0)
break;
printf("Enter the miles driven: ");
scanf("%lf",&miles);
if (miles<0)
break;
printf("The miles/gallon for this tank was: %lf", miles/gallons);
}
if (gallons<0) {
printf("The average is: %lf", sum/(count-1));
}
return 0;
}
double gallons=0;
double miles=0;
…
sum+=(miles/gallons);
Dividing zero by zero produces a NaN. Once there is a NaN, any arithmetic with it also produces a NaN.
Hm. In first iteration in sum+=(miles/gallons); you try to add to sum value 0/0. So, I think that you need to move this addition after inputs. Something like
printf("\nEnter the gallons used (-1 to end): ");
scanf("%lf",&gallons);
if (gallons<0)
break;
printf("Enter the miles driven: ");
scanf("%lf",&miles);
if (miles<0)
break;
printf("The miles/gallon for this tank was: %lf", miles/gallons);
sum+=(miles/gallons);
count++;
Related
I'm trying programming 1st time and not getting the output of this program.Though it looks simple but the code doesn't prints after taking the input like name, roll, marks obtained by student.
I have attached the screenshot of compiler.
Thank you!
#include<stdio.h>
int main()
{
int roll,phy,che,ca,total;
float percentage;
char name[20];
printf("enter the name of student: "); //studentname
scanf("%s",&name);
printf("enter the roll number: "); //roll number
scanf("%d",&roll);
printf("enter the marks obtained in phy,che,ca: "); //marks obtained/subject
scanf("%d%d%d ",&phy,&che,&ca);
//doesnt works from here.
total= (phy+che+ca); //calculating total marks
printf("the total marks obtained is %d\n",total);
percentage =total/3.0; //calculating percentage student got.
printf("the total percentage obtained is %d\n",percentage);
if(percentage>=80)
printf("first division\n"); //first division
else if(percentage>=60 && percentage<=80)
printf("second division\n"); //second division
else if(percentage>=60)
printf("third divison\n"); //third division
else if(percentage>=10)
printf("you failed!\n"); //failed
else
printf("invalid input\n"); //invalid input
return 0;
}
screenshot of the compiler
scanf("%d%d%d ",&phy,&che,&ca);
There is an extra blank character in format. So you should input a more character after you input 3 integers.
And you shouldn't use %d to print a float type variable, you should use %f.
I am getting an infinite loop for the program shown below when I run it twice without giving input for the first time. But when I give input on the first run then it is working perfectly.
But if I run it once and don't give input and rerun it, it results in an infinite loop.
How can I resolve the issue?
I am using VS Code.
Source code:
/* UNIT CONVERSION
kms to miles
inches to foot
cms to inches
pound to kgs
inches to meters
*/
#include <stdio.h>
int main(int argc, char const *argv[])
{
int x;
float a;
start:
printf("\nSelect the type of unit conversion you want\nkms to miles\tPRESS 1\ninches to foot\tPRESS 2\ncms to inches\tPRESS 3\npound to kgs\tPRESS 4\ninches to meters\tPRESS 5\nPRESS 0 TO EXIT\n");
scanf("%d", &x);
switch (x)
{
case 0:
goto end;
case 1:
printf("Enter the value in Km to be converted into miles\n");
scanf("%f", &a);
printf("%f kms is %f miles\n", a, 0.621371 * a);
goto start;
case 2:
printf("Enter the value in inches to be converted to foot\n");
scanf("%f", &a);
printf("%f inches is %f feet\n", a, 0.0833333 * a);
goto start;
case 3:
printf("Enter the value in cms to be converted to inches\n");
scanf("%f", &a);
printf("%f cms is %f inches\n", a, a * 0.393701);
goto start;
case 4:
printf("Enter the value in pound to be converted to kgs\n");
scanf("%f", &a);
printf("%f pound(s) is equal to %f kgs", a, a * 0.453592);
goto start;
case 5:
printf("Enter the value in inches to be converted to metres\n");
scanf("%f", &a);
printf("%f inch(es) is equal to %f metre(s)", a, a * 0.0254);
goto start;
default:
printf("You have not entered a valid input :(\n");
goto start;
}
end:
printf("You have successfully exited the program\n");
return 0;
}
If you don't give any input, by which you probably mean you just hit enter, scanf fails and the x variable will not be set.
if (scanf("%d", &x) != 1) {
x = -1;
}
This will set x to an invalid value in case no number was given. The code checks that scanf actually made exactly 1 conversion.
Always check scanf made the number of conversions requested.
And stop using goto. Use proper while, for, or do while loops.
I need to write a program where users can input their numbers as much as many as they defined, then the program will try to find which one is the lowest value and the highest value. The problems I face are:
When the program executed, the second line will wait on user's input (number) before the printf
The error "system" seems unreliable, sometimes works, sometimes doesn't work
The program only checks the last number entry, therefore it only shows the last number in min and max
You may give hints or corrections along the answers. Thank you very much.
#include <stdio.h>
float max(float num1){
float a=0, b;
if(num1 > a){
a=num1;
}
return a;
}
float min(float num2){
float x=100, y;
if(num2 < x ){
x=num2;
}
return num2;
}
int main(){
int times, interval;
float mini, maxi, data_Input;
printf("How many number would you like to type in ? : ");
scanf("%d\n",×);
printf("Type in the number: ");
scanf("%f", &data_Input);
for(interval=2; interval<=times; interval++){
printf("\nType in the number: ");
scanf("%f",&data_Input);
while(data_Input<0){
printf("Invalid Input! Please re-enter the number:");
scanf("%f",&data_Input);
}
while(data_Input>100){
printf("Invalid Input! Please re-enter the number:");
scanf("%f",&data_Input);
}
}
maxi= max(data_Input);
mini= min(data_Input);
printf("The Lowest Number is %.2f\n", mini);
printf("The Highest Number is %.2f\n", maxi);
return 0;
}
Output:
How many number would you like to type in? : 5
70
Type in the number :
Type in the number : 90.7
Type in the number : 99
Type in the number : 30
Type in the number : 50
The Lowest Number is 50.00
The Highest Number is 50.00
Okay, the thing is that you are not updating the data_input after every successive number is inputted. What you are doing is, comparing the last number to 0 or 100, which is logically incorrect.
How about you take the first number as input, then after every successive input, compare it with the min and max value. Here is the sample code.
#include <stdio.h>
float max(float num1, float num2){
if(num1 > num2){
return num1;
}
return num2;
}
float min(float num1, float num2){
if(num1 < num2){
return num1;
}
return num2;
}
int main(){
int times, interval;
float mini, maxi, data_Input;
printf("How many number would you like to type in ? : ");
scanf("%d\n",×);
printf("Type in the number: ");
scanf("%f", &data_Input);
// the first number will be minimum and maximum
mini = data_Input;
maxi = data_Input;
for(interval=2; interval<=times; interval++){
printf("\nType in the number: ");
scanf("%f",&data_Input);
// make it a composite if condition
while(data_Input<0 || data_Input>100){
printf("Invalid Input! Please re-enter the number:");
scanf("%f",&data_Input);
}
maxi= max(maxi, data_Input);
mini= min(mini, data_Input);
}
printf("The Lowest Number is %.2f\n", mini);
printf("The Highest Number is %.2f\n", maxi);
return 0;
}
The program checks the last number because you are calling the min and max function out of the for bracelets so instead you can call them inside the for bracelets like:
for(interval=2; interval<=times; interval++){
printf("\nType in the number: ");
scanf("%f",&data_Input);
while(data_Input<0){
printf("Invalid Input! Please re-enter the number:");
scanf("%f",&data_Input);
}
while(data_Input>100){
printf("Invalid Input! Please re-enter the number:");
scanf("%f",&data_Input);
}
maxi= max(data_Input);
mini= min(data_Input);
}
and instead of rewriting the same code you can just ask for the numbers inside the for loop and to initialize your interval to 1 so your main will look like:
int main(){
int times, interval;
float mini, maxi, data_Input;
printf("How many number would you like to type in ? : ");
scanf("%d\n",×);
for(interval=1; interval<=times; interval++){
printf("\nType in the number: ");
scanf("%f",&data_Input);
while(data_Input<0){
printf("Invalid Input! Please re-enter the number:");
scanf("%f",&data_Input);
}
while(data_Input>100){
printf("Invalid Input! Please re-enter the number:");
scanf("%f",&data_Input);
}
maxi= max(data_Input);
mini= min(data_Input);
}
printf("The Lowest Number is %.2f\n", mini);
printf("The Highest Number is %.2f\n", maxi);
return 0;
}
Solving the printf issue is easy. As stdout is line buffered (at least by default - it can be changed) it is flushed whenever a newline is inserted in the buffer. So, just add a newline after each message print, for example
printf("How many number would you like to type in ? : \n");
and you'll be fine.
Talking about the wrong calculation of min and max, your attempt has basically two big issues:
You are not acquiring times inputs, but only one. In fact, every time you call scanf you overwrite the same variable data_Input without performing any comparison with the previous inputs
You call min() and max() function only once, after the last input. Furthermore you try to compare the argument with a local variable that has local storage and a lifetime limited to the function itself so that at the next call it will be initialized again
In order to have a variable inside a function that it is initialized only the first time you can use static keyword. But it is not I suggest you to solve the issue.
In my opinion you don't need comparison functions: you can just update maxi and mini each time you get a new input (solving both the aforementioned issues at once):
int main(){
int times, interval;
float mini, maxi, data_Input;
printf("How many number would you like to type in ? : \n");
scanf("%d",×);
printf("Type in the number: ");
scanf("%f", &data_Input);
maxi = data_Input;
mini = data_Input;
for(interval=2; interval<=times; interval++){
printf("\nType in the number: \n");
scanf("%f",&data_Input);
while(data_Input<0){
printf("Invalid Input! Please re-enter the number:\n");
scanf("%f",&data_Input);
}
while(data_Input>100){
printf("Invalid Input! Please re-enter the number:\n");
scanf("%f",&data_Input);
}
/* Check input and, in case, update max and min */
if(data_Input > maxi)
maxi = data_Input;
if(data_Input < mini)
mini = data_Input;
}
printf("The Lowest Number is %.2f\n", mini);
printf("The Highest Number is %.2f\n", maxi);
return 0;
}
The comparison is performed inside the loop, so you don't need to store the inputs into an array.
You have plenty issues in your code.
Functions min & max do not make any sense
You do not check result of the scanf and you do not know if it was successfull
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
int main()
{
int times, interval;
float mini, maxi, data_Input;
do
{
printf("\nHow many number would you like to type in ? : ");
}while(scanf(" %d\n",×) != 1);
for(interval = 0; interval < times; interval++)
{
do
{
printf("\nType in the number: ");
}while(scanf(" %f",&data_Input) != 1 && (data_Input < 0 || data_Input > 100));
printf("%f\n", data_Input);
maxi = interval == 0 ? data_Input : MAX(maxi, data_Input);
mini = interval == 0 ? data_Input : MIN(mini, data_Input);
}
printf("The Lowest Number is %.2f\n", mini);
printf("The Highest Number is %.2f\n", maxi);
return 0;
}
When the program executed, the second line will wait on user's input (number) before the printf
Drop "\n" from "%d\n". It blocks until non-white space detected after the number and is not needed.
printf("How many number would you like to type in ? : ");
// scanf("%d\n",×);
scanf("%d",×);
printf("Type in the number: ");
If output still not seen when expected, flush it. Typically printing a '\n' will flush stdout, but not certainly.
printf("How many number would you like to type in ? : ");
fflush(stdout); // add
The error "system" seems unreliable, sometimes works, sometimes doesn't work
At least this issue: sequential check vs. checking both conditions together input validity.
Rather than
while(data_Input<0){
...
}
while(data_Input>100){
...
}
Test together.
while(data_Input<0 || data_Input>100){
...
}
The program only checks the last number entry, therefore it only shows the last number in min and max
True as code only compares values once with one call to max(). That function only compares the number to 0 rather than prior values. Likewise for min().
Consider an algorithm change
// Pseudo code for max
prompt How many number would you like to type in ? : "
get times
max_value = -INF // set to minimum possible float
for each value 1 to times
prompt "Type in the number: "
get data_Input
if data_Input > max_value
max_value = data_Input
print max_value
Here is a code which evaluates the average of 10 entered numbers. Problem is it doesn't seem to print the sum correctly (it's always equal to 0) after exiting the loop, everything else is working fine.
int count=0, n=10, c;
float sum=0, x;
do{
printf("x=");
scanf("%f", &x);
count++;
sum+=x;
}
while(count<n);
printf("Sum is %d", sum);
printf("\nCount is: %d", count);
printf("\nThe Average of the numbers is : %0.2f", sum/count);
getch();
}
Another question is how to exit the loop after a symbol is reached(i.e. without setting a limit to the number of integers to be entered).
Use the %f format specifier for floating point numbers.
printf("Sum is %f", sum);
To exit the loop on a symbol, you could check the return value from scanf. scanf returns the number of items read. If it returns 0 then the user didn't type a valid number.
while (1) {
printf("x=");
if (scanf("%f", &x) != 1) {
break;
}
...
}
break exits the current loop.
To answer your first question it should be printf("%f",sum) to print the correct sum. Since you are using float you have to use %f, if you use int it is %d. For your second question, you can do something like this (modify it accordingly):
int main(){
// Declare Variables
int count = 0; float sum = 0, currentNum = 0;
// Ask user for input
while(currentNum > -1)
{
printf("Enter integer to be averaged (enter -1 to get avg):");
scanf("%f",¤tNum);
if(currentNum == -1)
break;
// Check the entered number and computed sum
printf("You entered: %0.2f\n", currentNum);
sum += currentNum;
printf("Current sum: %0.2f\n", sum);
count++;
}
// Print Average
printf("Average is: %0.2f\n", sum/count);
return 0;
}
To answer your second question, you could do this:
scanf("%f", &x);
if (x==0) {
break;
}
This will break you out of the loop if you enter 0, then your loop can be infinite:
do {
} while(true)
For the second question, I think EOF may be the better solution:
while(scanf("%f", &x) != EOF)
I'm trying out programming in C for the first time, and applying it to some concrete stuff...
The program I'm creating with the problem deals with a while loop. The goal of the program is to calculate the average miles per gallon for a set of trucks. I want it to terminate as soon as -1 is inputted as the number of gallons consumed, but instead I have to input it twice, once for the number of gallons, and once for the number of miles. I have found this input to in fact be used as part of the calculation of the result. Here is the code:
#include <stdio.h>
int main()
{
int tanks, miles;
float gallons = 0, average = 0, miles_per_gallon = 0;
tanks = 0;
while (gallons != -1) {
tanks += 1;
miles_per_gallon = (float)miles / gallons;
average = average + miles_per_gallon;
printf("The miles / gallon for this tank was %.3f\n",
miles_per_gallon);
printf("Enter the gallons used (-1 to end): ");
scanf("%f", &gallons);
printf("Enter the miles driven: ");
scanf("%d", &miles);
}
average /= tanks;
printf("The overall average miles/gallon was %.3f", average);
return 0;
}
Here is some sample output:
C:\>gallons
Enter the gallons used (-1 to end): 12.3
Enter the miles driven: 700
The miles / gallon for this tank was 56.911
Enter the gallons used (-1 to end): 13.4
Enter the miles driven: 666
The miles / gallon for this tank was 49.701
Enter the gallons used (-1 to end): 17.3
Enter the miles driven: 644
The miles / gallon for this tank was 37.225
Enter the gallons used (-1 to end): 15.5
Enter the miles driven: 777
The miles / gallon for this tank was 50.129
Enter the gallons used (-1 to end): -1
Enter the miles driven: -1
The miles / gallon for this tank was 1.000
The overall average miles/gallon was 38.993
Thanks for any help.
The problem is that the sequence of statements in your code is such that the check for the loop's exit condition is not reached until after the second input is requested. You could add a check for -1 as soon as it's entered, and break out from the loop. Alternatively, you could ask for the miles to be entered ahead of the gallons.
for (;;) { /* This is a "forwver" loop; we break out from the middle */
tanks += 1;
miles_per_gallon = (float)miles / gallons;
average = average + miles_per_gallon;
printf("The miles / gallon for this tank was %.3f\n",
miles_per_gallon);
printf("Enter the gallons used (-1 to end): ");
scanf("%f", &gallons);
/* This is where you break from the loop: */
if (gallons == -1) return 0;
printf("Enter the miles driven: ");
scanf("%d", &miles);
}
Well you should be able to work it out by yourself, it is easy if you just change your loop or put a if statement after gallons input
while (gallons != -1) {
tanks += 1;
miles_per_gallon = ( float ) miles / gallons;
average = average + miles_per_gallon;
printf("The miles / gallon for this tank was %.3f\n", miles_per_gallon);
printf("Enter the gallons used (-1 to end): ");
scanf("%f", &gallons);
if(gallons==-1){
printf("Program terminated");
return 0;
}
printf("Enter the miles driven: ");
scanf("%d", &miles);
}
Check for the exit condition after reading gallons. I've made a couple of changes to you code --- because you are only breaking after reading gallons, i've changes the while condition to true. second I changed your test to <=0 as if 0 is entered you divide by 0 which will break your math, and anything less than 0 simply makes no sense. Thirdly I changed the calculation and reporting to after reading the values, so you don't divide by zero
while (1) {
printf("Enter the gallons used (-1 to end): ");
scanf("%f", &gallons);
if(gallons <= 0) break;
printf("Enter the miles driven: ");
scanf("%d", &miles);
tanks += 1;
miles_per_gallon = ( float ) miles / gallons;
average = average + miles_per_gallon;
printf("The miles / gallon for this tank was %.3f\n", miles_per_gallon);
}
while (gallons != -1) {
/* snip */
printf("Enter the gallons used (-1 to end): ");
scanf("%f", &gallons);
printf("Enter the miles driven: ");
scanf("%d", &miles);
}
Note that you only evaluate the exit criteria after asking both questions. If you want to avoid asking for the miles, you have to contort your loop a little further. It'll look something like this:
while (gallons != -1) {
/* snip */
printf("Enter the gallons used (-1 to end): ");
scanf("%f", &gallons);
if (gallons == -1)
break; /* exit the while loop */
printf("Enter the miles driven: ");
scanf("%d", &miles);
}
Of course, exiting a loop in the middle like this is a bit rough around the edges, but I don't immediately see a more convenient way to terminate the loop without asking the second question.