Code is ignoring IF command in C, Issues with FOR - c

I had posted on here before, but I was never able to get the help I needed.
I'm working on a school project and I can not get my program to work properly.
The program should prompt the user to enter the number of gallons used and
the number of miles driven for each of the 3 tanks of gas. The program should
then calculate and display the miles per gallon obtained for each tank. Once
processing is complete for the 3 tanks, the program will calculate the overall
mileage(total gallons / total miles) and display a friendly "Goodbye" message.
The issue i am having is that I can not get it to display to OVERALL Millage. it ends after looping 3 times.
I know different loop statements need conditions to be met, but I cant get the FOR loop to work properly. Im getting really frustrated, cause I know this should not be this hard.
Code
#include <stdio.h>
int main(void)
{
int miles,i=3;
float gallons, mg, overall = 0, avg = 0;
while(i>0)
{
printf("Enter the gallons used: ");
scanf("%f", &gallons);
printf("Enter miles driven: ");
scanf("%d", &miles);
mg = miles/gallons;
printf("The miles/gallon for this tank was : %f\n", mg);
overall += miles;
avg += gallons;i--;
}
if(gallons == 0)
{
printf("\n\n The overall miles/gallon was: %f\n", overall/avg);
exit(0);
}
return 0;
}

If I read your code correctly, then what is preventing the overall mileage from being printed is the following final if statement:
if (gallons == 0)
If you remove it, then the overall mileage should print. Use this pattern:
while (i > 0)
{
// your while loop here
}
printf("\n\n The overall miles/gallon was: %f\n", overall/avg);
exit(0);

This if (if (gallons == 0) {})block is out of while loop.
First, you need to move the if loop inside while loop.
and this if condition should be for variable i as follow and not for gallons.
if (i == 0)
{
printf("\n\n The overall miles/gallon was: %f\n", overall/avg);
}
In this case, after 3 iteration, value of i will be 0 so it will enter into the if block and calculate and print the overall miles/gallon.

Adding to Tim Biegeleisen's answer:
mg = miles/gallons;
What if gallons equals to 0? e.g. 0 miles for 0 gallons
This will lead to floating point exception.
A simple if-else can solve this problem!
if(!gallons)
mg = 0;
else
mg = miles/gallons;

Related

My output is not appearing properly

I apologize if I'm not formatting my question correctly. I am new to this site and new to programming.
I'm currently working on a C assignment and I believe I have most of the code done, but there is some tuning I can't seem to figure out. I would appreciate any feedback. Here is my code
#include <stdio.h>
#include <stdlib.h>
#define SENTINAL -1
double sumOfScores = 0;
double examScore = 0;
double sumOfExams = 0;
double average = 0;
double calculateAverage();
double main(void)
{
int i;
for (i = 1; i <= 4; ++i)
{
calculateAverage();
}
return 0;
}
double calculateAverage()
{
printf("Enter %d to terminate program. \n", SENTINAL);
while(examScore != SENTINAL)
{
printf("Enter test score: \n");
scanf("%lf", &examScore);
sumOfScores += examScore;
sumOfExams++;
average = sumOfScores / sumOfExams;
}
printf("The average of the test scores entered thus far is %.2lf \n\n", average);
return 0;
}
Here is my output
Enter -1 to terminate program.
Enter test score:
99
Enter test score:
98
Enter test score:
97
Enter test score:
96
Enter test score:
-1
The average of the test scores entered thus far is 77.80
Enter -1 to terminate program.
The average of the test scores entered thus far is 77.80
Enter -1 to terminate program.
The average of the test scores entered thus far is 77.80
Enter -1 to terminate program.
The average of the test scores entered thus far is 77.80
Here is what I would like it to look like
Enter -1 to terminate program.
Enter test score:
99
Enter test score:
98
Enter test score:
97
Enter test score:
96
Enter test score:
-1
The average of the test scores entered thus far is 77.80
Enter -1 to terminate program.
Enter test score:
95
Enter test score:
94
Enter test score:
93
Enter test score:
92
Enter test score:
-1
The average of the test scores entered thus far is (avg goes here)
I did not include an additional two sets of numbers in the output I am going for, but I would like to be able to do this with four sets of numbers. As soon as I enter (-1) to terminate the first set of numbers, it automatically spits me out the average of the first set for the remaining 3 sets before i can even input the numbers I would like to enter for those. Also, why is it giving me an avg of 77.8 for the first set of values when it should be up in the 90s?
I would recommend using local variables rather than global ones. That is to say, move these lines:
double sumOfScores = 0;
double examScore = 0;
double sumOfExams = 0;
double average = 0;
Here:
double calculateAverage()
{
double sumOfScores = 0;
double examScore = 0;
double sumOfExams = 0;
double average = 0;
// ...
This will cause the variables to be reset to 0 every time the function starts rather than leaving the garbage from the last time the function ran.
I think that the reason that you are getting the wrong average is that you are including -1 as one of the test scores. You read the value, then add it to the average BEFORE you check if the value is -1.
printf("Enter test score: \n");
scanf("%lf", &examScore);
// Is examScore equal to -1 here? It might be.
// Don't add it to sumOfScores without checking!
sumOfScores += examScore;
sumOfExams++;
average = sumOfScores / sumOfExams;
You either need to test if the value is -1 before you recalculate the average, or you need to restructure your loop such that the examScore != SENTINAL check is done between reading and recalculating the average.
Also, strictly speaking, there is no need to make all the averaging calculations while the loop is still running. You can save the average = sumOfScores / sumOfExams; line until after the loop has finished. Just a thought.
As Paul R said, you also have the incorrect function prototype for your main function. Valid prototypes for the main function can be found here

Galton Box/Bean Machine-C

I want to code a simple bean machine program. The program will accept user input for the number of balls and the number of slots, and will calculate the path of each ball. The number of balls in each slot will be printed as a histogram as well.
I tried my best to keep the code short and sweet, yet the best I have managed is 112 lines long. When I ran my code, I received no errors. However, the output seems to have run into some sort of an infinity loop (The '#' symbol which was used to represent numbers in the histogram keeps on printing forever for some reason unknown to me).
Apparently, there is something wrong with my logic somewhere... or a silly little mistake in syntax(but it would have shown up as error, wouldn't it?)... In a nutshell, I cannot figure out exactly what is the problem. (I attempted to walk through the whole code process from start to finish, but my mind kept getting tangled up somewhere in the middle of the code, nowhere near the end of the code either).
Where exactly does my logic go wrong?(Or have I taken the wrong approach to the whole problem?) I do not wish to know the correct code, so that I am able to learn during the whole process of re-editing my code.
Any help (hopefully no model-code answers though), even as a single comment, is tremendously appreciated! :)
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <stdbool.h>
#include <time.h>
//Pls excuse my extensive use of libraries even though I don't really use them
int intchecker(float x)
{
if (floor(x)==x && ceilf(x)==x)
{
return 0;
}
else {
return 1;
}
}
int main(){
char line[] = " +----+----+----+----+----+----+----+----+----+----+---+";
char numbers[] = " 0 5 10 15 20 25 30 35 40 45 50";
float balls,slots;
int slotarry[9],tlevel,ballnum,column,lcounter=0,slotsduplicate=1,y;//tlevel-number of levels in the triangle
srand(time(NULL));
int r;
printf("==========================================================\nGalton Box Simulation Machine\n==========================================================\n");
printf("Enter the number of balls [5-100]: ");
scanf("%f",&balls);
while (balls>100 || balls<5) {
printf("\nInput is not within the range. Please try again.");
printf("\nEnter the number of balls [5-100]: ");
scanf("%f",&balls);
}
while (intchecker(balls)==1) {
printf("\nInput is not an integer. Please try again.");
printf("\nEnter the number of balls [5-100]: ");
scanf("%f",&balls);
}
printf("Enter the number of slots [2-10] : ");
scanf("%f",&slots);
while (slots>10 || slots<2) {
printf("\nInput is not within the range. Please try again.");
printf("\nEnter the number of slots [2-10] : ");
scanf("%f",&slots);
}
while (intchecker(slots)==1) {
printf("\nHow can there be a fraction of a slot? Please re-enter slot number.");
printf("\nEnter the number of slots [2-10] : ");
scanf("%f",&slots);
}
tlevel=slots-1;
for(ballnum=1,column=0;balls>0;balls--,ballnum++,column++){
if (column%5==0){
printf("\n");
}
if (ballnum<10){
printf("[0%d]",ballnum);
}
else{
printf("[%d]",ballnum);
}
for(;tlevel>0;tlevel--){
r = rand() % 2;
if (r==0){
printf("R");
}
else {
printf("L");
lcounter++;
}
}
slotarry[lcounter]++;
tlevel=slots-1;
lcounter=0;
printf(" ");
}
printf("\n\n%s",numbers);
printf("%s",line);
char line2[] = "\n +----+----+----+----+----+----+----+----+----+----+---+";
for(;slotsduplicate<=slots;slotsduplicate++){
if (slotsduplicate<10){
printf("0%d|",slotsduplicate);
}
else{
printf("%d|",slotsduplicate);
}
y=slotarry[slotsduplicate];
if (y==0){
printf(" 0");
}
else{
for (;y>0;y--){
printf("#");
}
printf(" %d",slotarry[slotsduplicate]);
}
printf("%s",line2);
}
return 0;
}
Note:This is not completely error-free. This is just my first draft. I just wish to find out why there is an infinite loop.
Here's how I found the problem. First of all, I think it is a bit of a code smell to have a for loop without anything in the initial assignment section. Couple that with the fact that it seems to print # forever, and it looks like y has a garbage value at the beginning of the loop to print the #s.
So I ran your code in the debugger and paused it when it started printing loads of hashes. I checked the value of y and sure enough it was some unfeasibly high number.
Then I checked where y comes from and found you get it from slotarray. I printed it in the debugger and found that all the values in it were unfeasibly high or massively negative numbers. Obviously, slotarray wasn't being initialised correctly, so I looked for where it was initialised and bingo!
Stack variables (of which slotarray is one) must be explicitly initialised in C. I fixed your code with a call to memset.
The whole debugging process I have just outlined took something less than a minute.
ETA As #EOF points out, there is another bug in that slotarray is defined to contain nine slots (indexed 0 - 8) but you allow people to enter 10 slots. This is a buffer overflow bug.

How to make a table in C using loops

How do you make a table like the pic (you are using the ideal gas law). The volume values should start on the left-most column with the start volume and increase in equal steps
such that the right-most column's volume is the stop volume. For each entry in the table, compute the pressure at the given temperature and volume, Please help.
Volume: 10.00 --- 18.89 --- 27.78 --- 36.67
Temp:
300.00 - 24.94 --- 13.20 --- 8.98 --- 6.80
400.00 - 33.26 --- 17.61 ---11.97--- 9.07
500.00 - 41.57 --- 22.01 ---14.97--- 11.34
#include <stdio.h>
int main(void)
{
float vol1, vol2;
float temp1, temp2;
float R = 8.314;
int mole;
int rows;
int columns = 8;
printf("Enter the starting volume (in meters cubed):");
scanf("%f",&vol1);
while(vol1<0)
{
printf("Error: Enter a number that is positive:");
scanf("%f",&vol1);
}
printf("Enter the ending volume (in meters cubed):");
scanf("%f",&vol2);
while(vol2<0)
{
printf("Error: Enter a number that is positive:");
scanf("%f",&vol2);
}
printf("Next enter the starting temperature (in kelvin):");
scanf("%f",&temp1);
while(temp1<0)
{
printf("Error: Enter a number that is positive:");
scanf("%f",&temp1);
}
printf("Enter the ending temperature (in kelvin):");
scanf("%f",&temp2);
while(temp2<0)
{
printf("Error: Enter a number that is positive:");
scanf("%f",&temp2);
}
printf("Enter the number of moles:");
scanf("%f",&mole);
while(mole<0)
{
printf("Error: Enter a number that is positive:");
scanf("%f",&mole);
}
printf("How many rows should the temperature value have?\n");
scanf("%d",&rows);
while(rows<1)
{
printf("Error: Enter a number that is positive:");
scanf("%d",&rows);
}
return 0;
}
I think I know what you're asking, so I'll reword your question so it is clear. You are trying to print out a 2D table with values that change in equal steps in the x direction (volume in this case) and equal values in the y direction (temperature in this case). I think that vol1 is starting volume and vol 2 is ending volume? and same for tmeperature?
The key to doing this is to use nested for loops
So something like this
for (x=vol1; x<vol2; x + volstepsize)
{
for(y=temp1; y<temp2; y + tempstepsize)
{
compute gas law equation here using x and y and do a print statement
}
perform a blank print line statement here to indent/start the next row
}
By having nested for loops you will print out row and column sequentially; this is a fundamental concept for accessing and writing 2D tables.
Hope that helps!

Too few arguments in function to call [C program]

So, I have an assignment due tomorrow night for my online C programming class, and I am having some problems with my coding at the moment. I have brought the code to my teacher, but she doesn't seem to understand that she is being paid to teach me, not tell me that something is wrong with my code. I would appreciate if someone could take a look at the code and help me fix it. Code is located below. The location where I get my error is in main when calling the printtripSummary.
#include <stdio.h>
void welcomeMessage();
void askuserForInput();
void printtripSummary(float avgMiles, float minCost, float maxCost, float travelMiles);
int main()
{
/* Call the functions */
welcomeMessage();
askuserForInput();
printtripSummary();
printf("\nThank you, please drive safely and have a nice trip!\n");
return 0;
}
void welcomeMessage()
{
printf("Welcome to the Trip Planner!\n");
printf("So you are ready to take a trip? Let me help you plan for\n");
printf("your fuels costs and required stops to fill up your tank.\n");
printf("============================================================\n");
printf("Please provide answers to the prompts below and I will\n");
printf("display a summary for you when I have computed the results.\n");
printf("============================================================\n");
}
void askuserForInput()
{
float avgMiles, minCost, maxCost, travelMiles;
do{
printf("Please input your car's average miles per gallon (enter 0 to quit)>> ");
scanf_s("%f", &avgMiles);
if (avgMiles == 0)
break;
printf("Please tell me the range of fuel costs you expect to pay (per gallon>>)\n");
printf("The lowest per gallon cost of fuel is>> ");
scanf_s("%f", &minCost);
printf("The highest per gallon cost of fuel is>> ");
scanf_s("%f", &maxCost);
printf("Please tell me how many miles you plan to travel>> ");
scanf_s("%f", &travelMiles);
printtripSummary(avgMiles, minCost, maxCost, travelMiles);
} while (avgMiles != 0);
}
void printtripSummary(float avgMiles, float minCost, float maxCost, float travelMiles)
{
float avgGal, mingasPrice, maxgasPrice;
do{
avgGal = travelMiles / avgMiles;
mingasPrice = avgGal * minCost;
maxgasPrice = avgGal * maxCost;
printf("You will be required to purchase %.2f gallons of fuel.\n", avgGal);
printf("The price will range between %2f and $%.2f.\n", mingasPrice, maxgasPrice);
} while (avgMiles != 0);
}
Comment out the function call in main like this (Line 13):
//printtripSummary();
Because you call the function already in askuserForInput(); and this function get called in main
OR if you want to call the function also in main your have to pass the required arguments which are:
(float avgMiles, float minCost, float maxCost, float travelMiles)
Also you have a endless loop in the function printtripSummary(); Because you have a do...while loop which checks if avgMiles != 0, but since your not changing the value of avgMiles in this loop it's endless!
On line 13 you're calling the printtripSummary function without passing any arguments to it. You have to provide the 4 arguments the function definition specifies (avgMiles, minCost, maxCost, travelMiles).

Temperature Converter Challenge [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I was doing a coding challenge for a website, the premise was:
In this challenge, write a program that takes in three arguments, a start temperature (in
Celsius), an end temperature (in Celsius) and a step size. Print out a table that goes from > the start temperature to the end temperature, in steps of the step size; you do not
actually need to print the final end temperature if the step size does not exactly match.
You should perform input validation: do not accept start temperatures less than a lower
limit (which your code should specify as a constant) or higher than an upper limit (which
your code should also specify). You should not allow a step size greater than the
difference in temperatures. (This exercise was based on a problem from C Programming
Language).
I got the same results as the solution did, but I'm curios as to why their solution is more efficient (I'd presume it is). Anyone able to explain it to me? Their solution is first followed by mine.
#include <stdio.h>
#define LOWER_LIMIT 0
#define HIGHER_LIMIT 50000
int main(void) {
double fahr, cel;
int limit_low = -1;
int limit_high = -1;
int step = -1;
int max_step_size = 0;
/* Read in lower, higher limit and step */
while(limit_low < (int) LOWER_LIMIT) {
printf("Please give in a lower limit, limit >= %d: ", (int) LOWER_LIMIT);
scanf("%d", &limit_low);
}
while((limit_high <= limit_low) || (limit_high > (int) HIGHER_LIMIT)) {
printf("Please give in a higher limit, %d < limit <= %d: ", limit_low, (int) HIGHER_LIMIT);
scanf("%d", &limit_high);
}
max_step_size = limit_high - limit_low;
while((step <= 0) || (step > max_step_size)) {
printf("Please give in a step, 0 < step >= %d: ", max_step_size);
scanf("%d", &step);
}
/* Initialise Celsius-Variable */
cel = limit_low;
/* Print the Table */
printf("\nCelsius\t\tFahrenheit");
printf("\n-------\t\t----------\n");
while(cel <= limit_high) {
fahr = (9.0 * cel) / 5.0 + 32.0;
printf("%f\t%f\n", cel, fahr);
cel += step;
}
printf("\n");
return 0;
}
My solution:
#include <stdio.h>
#include <stdlib.h>
#define LOW 0
#define HIGH 50000
int main(void)
{
int lower, higher, step, max_step;
float cel, fahren;
printf("\nPlease enter a lower limit, limit >= 0: ");
scanf("%d", &lower);
if (lower < LOW)
{
printf("\nERROR: Lower limit must be >= 0.");
exit(1);
}
printf("\nPlease enter a upper limit, limit <= 50000: ");
scanf("%d", &higher);
if (higher > HIGH)
{
printf("\nERROR: Upper limit must be <= 50,000.");
exit(1);
}
printf("\nPlease enter an increment amount, 0 < step <= 10: ");
scanf("%d", &step);
max_step = higher - lower;
if (step > max_step)
{
printf("\nERROR: Step size cannot exceed difference between higher and lower limit.");
exit(1);
}
printf("Celsuis \tFahrenheit\n");
printf("------- \t-----------\n\n");
cel = (float)lower;
while (cel < higher)
{
fahren = cel * 9/5 + 32;
printf("%f \t%f\n", cel, fahren);
cel = cel + step;
}
return 0;
}
Hmm, which is more efficient... before making that claim we need some metrics, what are we talking about here? Run time? Binary size?
Just a quick example… we can compile both solutions and run them with the "time" command and a worst case (0-50000 with a step of 1) to see what type of times we're using:
"Their" solution size:
text data bss dec hex filename
1937 276 8 2221 8ad a.out
"Their" solution running time:
user 0m 0.024s
sys 0m 0.601s
Your solution size:
text data bss dec hex filename
2054 276 8 2338 922 a.out
Your solution running time:
user 0m 0.025s
sys 0m 1.047s
So your solution takes longer and has a larger image size. Can we say now that "they" have a more efficient program? Not really, the time isn't totally accurate on this scale (and with other things happening in the system) so we'd need a number of runs. Averaged over four* runs:
// you
user 0.0178
system 0.9015
// "them"
user 0.016
system 0.914
So no, they are not really more "efficient" then you are.
There are some trivial things we can do to increase the "efficiency" here, but because the solutions are so similar, and the code is so trivial (a single stepping traversal) I'm not really sure if it matters all that much.
As far as "efficient" code size, you'll note that your .text size is larger than the other solution. Your messages are more verbose and readable, so you take a hit on size. Is that more efficient? Perhaps if size is important, but personally I think readability is more important unless we're talking an embedded solution.
* - you need a lot more runs and a more sensitive timing mechanism, but this is just a quick example

Resources