My output is not appearing properly - c

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

Related

C program, can't for the life of me figure it out

Ok so I have to increment a function into my code to get it to load a bunch of numbers that eventually will reach the sqrt of the number that is input my the user, all by using a while loop. The problem is, the number does not go into the function, and it loops indefinitely because the false is never reached. Any help?
#include <stdio.h>
#include <math.h>
int main(void)
{
double in, out, var, new_guess, old_guess;
printf("Enter a number: ");
scanf("%lf", &in);
while(fabs(in - sqrt(old_guess)) >= 1e-5) {
new_guess = (old_guess + (in / old_guess)) / 2.0;
printf("%11.5lf", old_guess);
}
printf("Estimated square root of %11.5lf: %11.5lf\n", in, new_guess);
return 0;
}
Once you get all your syntax issues resolved, you will still never get the desired result because the math in your predictor/corrector method will never converge. Specifically, fabs(in - sqrt(old_guess)) will always be >= 1e-5 as in will always be greater than the sqrt of old_guess.
Further, if you are using a predictor/corrector method to compute the square root of a number, it rather defeats the purpose to use sqrt in the iteration. If you were going to use the sqrt function to find the answer, you could simply do:
double answer = sqrt (in); /* problem solved */
The purpose of an iterative method is to converge on a solution by using either a rate or average difference to repeatedly refine your guess until it satisfies some condition like a error tolerance between repeated terms (which it appears you are attempting to do here)
To iteratively find the square root of a number using the method you are attempting to use, you first find the next lower or higher perfect square of the number entered by the user. A simple brute force of starting at 1 and incrementing x until x * x is no longer less than in is fine.
You then divide the input by the perfect square to predict the answer, and then take the average of the input divided by the predicted answer plus the predicted answer to correct for error between the terms (and repeat until your error tolerance is reached)
note you should also include an iteration limit to prevent against an endless loop if your solution does not converge for some reason.
Putting it altogether, you could do something similar to:
#include <stdio.h>
#include <math.h>
#define ILIM 64 /* max iteration limit */
#define TOL 1e-5 /* tolerance */
int main(void)
{
double in, n = 0, new_guess, old_guess, root = 1;
printf ("Enter a number: ");
if (scanf ("%lf", &in) != 1) {
fprintf (stderr, "error: invalid input.\n");
return 1;
}
while (root * root < in) /* find next larger perfect square */
root++;
/* compute initial old/new_guess */
old_guess = (in / root + root) / 2.0;
new_guess = (in / old_guess + old_guess) / 2.0;
/* compare old/new_guess, repeat until limit or tolerance met */
while (n++ < ILIM && fabs (new_guess - old_guess) >= TOL) {
old_guess = new_guess;
new_guess = (in / old_guess + old_guess) / 2.0;
}
printf ("Estimated square root of %.5f: %.5f\n", in, new_guess);
printf ("Actual : %.5f\n", sqrt (in));
return 0;
}
(note: sqrt is only used to provide a comparison with your iterative solution)
Example Use/Output
$ ./bin/sqrthelp
Enter a number: 9
Estimated square root of 9.00000: 3.00000
Actual : 3.00000
$ ./bin/sqrthelp
Enter a number: 9.6
Estimated square root of 9.60000: 3.09839
Actual : 3.09839
$ ./bin/sqrthelp
Enter a number: 10
Estimated square root of 10.00000: 3.16228
Actual : 3.16228
$ ./bin/sqrthelp
Enter a number: 24
Estimated square root of 24.00000: 4.89898
Actual : 4.89898
$ ./bin/sqrthelp
Enter a number: 25
Estimated square root of 25.00000: 5.00000
Actual : 5.00000
$ ./bin/sqrthelp
Enter a number: 30
Estimated square root of 30.00000: 5.47723
Actual : 5.47723

Unknown test case error in C program

This a question I have to submit for an assignment, hence it has to be evaluated online. My program is running correctly for 6 out of 7 test cases. Only 3 test cases are provided and they are as shown:
Sports or Economy Car
Help Mr.Kamath to check whether his vehicle is an economy car or not. The program should display “There is a gas hog” if the mileage is less than or equal to 15 Km and the program should display “It is an economy car” if the mileage is not less than 30 Km. Otherwise display "Fuel Economy". Write a C program to get the values of a Car variables from the user. Create a structure called Car. Order of the input values entered should be according to the structure variables
struct Car{
float startKm;
float endKm;
float litres;
};
Test Case
Input 1
30
50
5
Output 1
There is a gas hog
Input 2
40.5
80.5
1.5
Output 2
Fuel Economy
Input 3
30
0
5
Output 3
You have entered 0
My code:
#include<stdio.h>
struct Car
{
float startKm;
float endKm;
float litres;
};
int main()
{
struct Car c;
float m;
scanf("%f",&c.startKm);
scanf("%f",&c.endKm);
scanf("%f",&c.litres);
m=(c.endKm-c.startKm)/c.litres;
if(c.startKm<=0||c.endKm<=0||c.litres<=0)
{
printf("You have entered 0"); return 0;
}
else if(m<=15)
{
printf("There is a gas hog");
}
else if(m>=30)
{
printf("It is an economy car");
}
else
{
printf("Fuel Economy");
}
return 0;
}
These are the test cases(unknown):
These is my evaluation output:
PS: I am facing similar problems in many such programs with several test cases.
I also asked a similar question Cannot identify error with code, failing a test case
It would be helpful if someone suggests how to approach such unknown test cases.
If I'm not mistaken you should be able to start from 0 km. I went ahead and tried my own test case:
Starting km 0, Ending km 25, Liters used 1
if(c.startKm < 0 || c.endKm <= c.startKm || c.litres <= 0)

Code is ignoring IF command in C, Issues with FOR

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;

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.

Use fscanf to read two lines of integers

I want to ask something that I write in C.
I use the fopen() command to open and read a text file that contains only two lines. in
first line is an integer N number, and in the second line is the N integer numbers that the first line says.
Eg.
-------------- nubmers.txt --------------
8 <-- we want 8 numbers for the 2nd line
16 8 96 46 8 213 5 16 <-- and we have 8 numbers! :)
but I want to take restrictions when the file openend.
the number N should be between 1 ≤ Ν ≤ 1.000.000. If not then show an error message. If the file is ok then the programm continue to run with another code.
Here is what I done until now:
int num;
....
fscanf(fp,"%d",&num); // here goes the fscanf() command
if(num<1 || num>1000000) // set restrictions to integer
{
printf("The number must be 1<= N <= 1.000.000",strerror(errno)); // error with the integer number
getchar(); // wait the user press a key
return 0; // returning an int of 0, exit the program
}
else // if everything works.....
{
printf("work until now"); // Everything works until now! :)
getchar(); // wait the user press a key
return 0; // returning an int of 0, exit the program
}
But the problem is that the restriction checks only for the first line number , it's correct though, but don't read the numbers in the second line.
What I mean is that :
Lets say that I have the number 10 in the first line.
The code will analyze the number, will check for restrictions and will proceed to the 'else' part
else // if everything works.....
{
printf("work until now"); // Everything works until now! :)
getchar(); // wait the user press a key
return 0; // returning an int of 0, exit the program
}
..and it will said that everything is working.
But what if I have 20 numbers in the second line? -when I need only 10
Eg.
-------------- nubmers.txt --------------
10
16 8 96 46 8 213 5 16 8 9 21 5 69 64 58 10 1 7 3 6
So I hoped be as cleared as I could. My question is that I need a code in the program, besides the 1st restriction, that have also another one restriction under the first that will read the second line of the txt file with the numbers and check if there are as many numbers as the first line says!
How do I do that?
If you guys want any other declarations feel free to ask!
Hope I was clear with my problem :)
This will check the number of integers and report too many or not enough. The integers are not saved except for each one being read into the value. Do you want to store each integer?
fscanf(fp,"%d",&num); // here goes the fscanf() command
if(num<1 || num>1000000) // set restrictions to integer
{
printf("The number must be 1<= N <= 1.000.000",strerror(errno)); // error with the integer number
getchar(); // wait the user press a key
return 0; // returning an int of 0, exit the program
}
else // if everything works.....
{
int i = 0;
int value = 0;
while ( fscanf ( fp, "%d", &value) == 1) { // read one integer
i++; // this loop will continue until EOF or non-integer input
}
if ( i > num) {
printf ( "too many integers\n");
}
if ( i < num) {
printf ( "not enough integers\n");
}
getchar(); // wait the user press a key
return 0; // returning an int of 0, exit the program
}
use a loop that takes the first num and checks is is the number of integers in next line:
int z = num;
while(z--){
if (getchar() == EOF)
printf("err")
}
Do it like this:
fscanf(fp,"%d",&num);
// next lines of code (restrictions). Then place the below code before getchar in the else
int temp[num+1];// space to store num integers to temp and 1 space to check for extra number
for(i=0;i<num;i++)
{
if(fscanf(fp,"%d",&temp[i]) != 1)// fscanf will automatically read 2nd line and store them in temp array
//error ! Less numbers in file !
}
if(fscanf(fp,"%d",&temp[num]==1) //if still numbers can be scanned
//Extra numbers found in line 2

Resources