How to add total of multiple repeats in C? - c

I am writing a simple C program which takes data from user and does some maths. Here is my code:
#include <stdio.h>
int main(void) {
int semester_1,grade_1,grade_2,grade_3,subtotal,total_marks,average;
printf("Enter number of semester you to check");
scanf("%d", &semester_1);
while (semester_1 > 0) {
printf("Enter marks for first subject");
scanf("%d", &grade_1);
printf("Enter marks for second subject");
scanf("%d", &grade_2);
printf("Enter marks for third subject");
scanf("%d", &grade_3);
subtotal = grade_1 + grade_2 + grade_3;
total_marks = subtotal / 300 * 100;
printf("Your average this semester is %d", total_marks);
semester_1--;
}
average = semester_1 / 100 * total_marks;
printf("Your final average for all semesters is %d", average);
}
The problem with this code is that when I run the program returns 0 for final average for all semesters.
I wanted to get the final average for all semesters. Lets say if user enters 3 for numbers of semester they want to check and then they will be enter marks 3 times and then final average will be displayed, but it only gives 0.

#include <stdio.h>
int main(void) {
int semester_1,grade_1,grade_2,grade_3,subtotal,total_marks,average;
printf("Enter number of semester you to check");
scanf("%d", &semester_1);
while (semester_1 > 0) {
printf("Enter marks for first subject");
scanf("%d", &grade_1);
printf("Enter marks for second subject");
scanf("%d", &grade_2);
printf("Enter marks for third subject");
scanf("%d", &grade_3);
subtotal = grade_1 + grade_2 + grade_3;
total_marks = subtotal / 300.0 * 100.0;
printf("Your average this semester is %d", total_marks);
semester_1--;
}
average = semester_1 / 100.0 * total_marks;
printf("Your final average for all semesters is %d", average);
}
Rounding errors

It is probably because here:
total_marks = subtotal / 300 * 100;
subtotal is less than 300 * 100. And since both the operands of / are of type int, integer division is performed resulting in total_marks becoming 0.
Fix it by changing the type of total_marks to float, or more preferably, double. Then, cast one of the operands of / to float if you changed total_marks's type to float or double if you changed total_marks's type to double. The cast makes sure that integer division is not performed and floating-point division is performed.
You might need to do the same with average.
Fixed Code:
#include <stdio.h>
int main(void) {
int semester_1, grade_1, grade_2, grade_3, subtotal; /* Better to use an array */
double total_marks, average;
printf("Enter number of semester you to check");
scanf("%d", &semester_1);
while (semester_1 > 0) {
printf("Enter marks for first subject");
scanf("%d", &grade_1);
printf("Enter marks for second subject");
scanf("%d", &grade_2);
printf("Enter marks for third subject");
scanf("%d", &grade_3);
subtotal = grade_1 + grade_2 + grade_3;
total_marks = (double)subtotal / 300 * 100; /* Note the cast */
printf("Your average this semester is %f", total_marks); /* Note the change in the format specifier */
semester_1--;
}
average = (double)semester_1 / 100 * total_marks; /* Note the cast */
printf("Your final average for all semesters is %f", average); /* Note the change in the format specifier */
}

Your code has several issues. The first is the one pointed out by Cool Guy: dividing small integer by bigger integer will lead to the result being zero due to integer truncation.
The second is that you aren't keeping a running total, and you're decrementing the number of semesters for your loop counter.
You should add a new variable that stores the cumulative sum of each semester, and you should save the initial value of semester_1
(Also, style-wise,
for (int i = 0; i < num_semesters; i++)
is much more readable than (and preserves the value of num_semesters)
while(semester_1 > 0)
)

Related

C: 2 User input fields when requesting 3

From what I understand I should be getting 3 user input prompts, Trip Distance, Car MPG, and Gas Dollars Per Gallon to calculate total trip cost. Whenever I run the code, I only get prompted to input trip distance and car mpg, it skips gas dpg. How do I get it to recognize 3 user inputs?
int main() {
int miles;
double milesPG;
double dollarsPG;
double gasCost = (miles * (1.0 / milesPG) * dollarsPG);
printf("Input trip distance: ", miles);
scanf("%d", &miles);
printf("\nInput car miles per gallon: ", milesPG);
scanf("%0.2lf", &milesPG);
printf("\nInput gas dollars per gallon: ", dollarsPG);
scanf("%0.2lf", &dollarsPG);
printf("\nTotal trip cost is %0.2lf \n", gasCost);
return 0;
}
There are multiple problems in your code:
you do not include <stdio.h>
you compute gasCost before the values of miles, milesPG and dollarsPG are input. Since these variables are uninitialized, this has undefined behavior.
passing the uninitialized values to the printf() statements for prompting is useless and actually has undefined behavior as these variables are uninitialized.
the conversion format "%0.2lf" is invalid for scanf(). You cannot specify how many places to input, just the maximum number of bytes to read, which is not useful in your case.
Here is a modified version:
#include <stdio.h>
int main() {
int miles;
double milesPG;
double dollarsPG;
printf("Input trip distance: ");
if (scanf("%d", &miles) != 1)
return 1;
printf("\nInput car miles per gallon: ");
if (scanf("%lf", &milesPG) != 1)
return 1;
printf("\nInput gas dollars per gallon: ");
if (scanf("%lf", &dollarsPG) != 1)
return 1;
double gasCost = (miles * (1.0 / milesPG) * dollarsPG);
printf("\nTotal trip cost is %.2f\n", gasCost);
return 0;
}

C program for aggregate marks and percentage

If the marks obtained by a student in five different subjects are input through the keyboard, write a program to find out the aggregate marks and percentage marks obtained by the student. Assume that the maximum marks that can be obtained by a student in each subject is 100.
My code:
#include<stdio.h>
int main()
{
int sub1, sub2, sub3, sub4, sub5, aggregate_marks;
float percentage_marks;
printf("Enter the marks of sub1: ");
printf("\nEnter the marks of sub2: ");
printf("\nEnter the marks of sub3: ");
printf("\nEnter the marks of sub4: ");
printf("\nEnter the marks of sub5: ");
scanf("%d%d%d%d%d",&sub1, &sub2, &sub3, &sub4, &sub5);
aggregate_marks = sub1+sub2+sub3+sub4+sub5;
printf("Aggregate marks is: %d",aggregate_marks);
percentage_marks = (aggregate_marks/500)*100;
printf("\nPercentage marks is: %f\n",percentage_marks);
return 0;
}
Output:
Enter the marks of sub1:
Enter the marks of sub2:
Enter the marks of sub3:
Enter the marks of sub4:
Enter the marks of sub5: 78
54
67
87
75
Aggregate marks is: 361
Percentage marks is: 0.000000
Program ended with exit code: 0
The input marks are not aligned with subjects and percentage marks aren't showing.
What is wrong here?
Caveat: This isn't a direct answer to your problem, but I want you to get off on a good footing. It could/should be a comment except for the code refactoring.
When you use sub1, sub2, ..., this "cries out" for an array implementation (e.g.):
int subs[5];
And, a loop instead of separate printf/scanf pairs for each scalar value.
When starting out in programming, it isn't always easy to see the use case for an array. It might have been [more] obvious if you had to enter a much larger number of marks (e.g. 1000).
Anyway, here's a version of your code that implements an array:
#include <stdio.h>
#define SUBMAX 5
int
main(void)
{
int idx;
int curmark;
int subs[SUBMAX];
int aggregate_marks = 0;
float percentage_marks;
for (idx = 0; idx < SUBMAX; ++idx) {
printf("Enter the marks of sub%d: ",idx + 1);
fflush(stdout);
scanf(" %d",&curmark);
subs[idx] = curmark;
aggregate_marks += curmark;
}
printf("Aggregate marks is: %d\n", aggregate_marks);
percentage_marks = (aggregate_marks / 500.0) * 100;
printf("Percentage marks is: %f%%\n", percentage_marks);
return 0;
}
Input marks are not aligned because you first print all the 5 printf statements and then execute scanf for 5 inputs. To resolve this issue you can first use one printf statements and then execute scanf for 1 subject. Ex:
printf("Enter the marks of first subject(out of 100): ");
scanf("%f",&sub1);
Percentage marks are not showing because in C if two variables or constants are integer then any mathematical operation between them yeilds an integer.
In your case
percentage_marks = (aggregate_marks/500)*100;
First (aggregate_marks/500) operation executes. If we take your input then
aggregate_marks = 361 and (361/500) = 0.722 but as 361 and 500 both are integer it yields 0.
Second Operation (0 * 100) yeilds 0. But when it initializes to percentage_marks as it is a float it promoted from int to float and percentage_marks = 0.000000.
To resolve this issue you need to take all subject marks and aggregate_marks float. Ex:
float sub1,sub2,sub3,sub4,sub5;
float total, aggregate_marks, percentage_marks;
After making those changes your code looks like:
//program to calculate the aggregate and percentage marks of a student
#include<stdio.h>
int main()
{
float sub1,sub2,sub3,sub4,sub5;
float total, aggregate_marks, percentage_marks;
printf("Enter the marks of first subject(out of 100): ");
scanf("%f",&sub1);
printf("Enter the marks of second subject(out of 100): ");
scanf("%f",&sub2);
printf("Enter the marks of third subject(out of 100): ");
scanf("%f",&sub3);
printf("Enter the marks of fourth subject(out of 100): ");
scanf("%f",&sub4);
printf("Enter the marks of fifth subject(out of 100): ");
scanf("%f",&sub5);
aggregate_marks = (sub1 + sub2 + sub3 + sub4 + sub5); // formula to calculate aggregate marks
percentage_marks = (aggregate_marks / 500) * 100; // formula to calculate percentage marks
printf("Aggregate marks: %.2f\n", aggregate_marks);
printf("Percentage marks: %.2f\n", percentage_marks);
return 0;
}
First of all you can use 'Enter the marks of sub1:' in scanf itself for eg-
scanf("Enter the marks of sub1: %d\n",&sub1);
For your percentage calculations you should multiply the aggregate by 100 first and then divide it by zero because when you divide 361 by 500 it should give 0.722 but in C it treats this as integer and round off as 0.
Here's the right code-
percentage_marks = (aggregate_marks*100)/500;
This should solve your problem.

Issues finding average of elements

Working with Repl.it and trying to use a function in C to average the elements in a variable length array. My program works fine in every other i/o area other than the average which returns:
The average for that day is: -nan. Any insight on what the issue may be?
The goal is to receive user input as a double(for example, how many pints of blood were taken per hour over a 7 hr period and then use a function call to calculate the average amount for that seven hour period.
New code is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
double average(int size, float ary[*]);
int main(void)
{
char dayOne[8], dayTwo[8];
int size;
float ave;
printf("Over how many hours do you want to view donation amounts?: ");
scanf("%d", &size);
if (size < 7 || size > 7)
size = 7;
printf("Enter day that you want to see average donation amount for: ");
scanf("%s", dayOne);
{
float ary[size];
for (int i = 0; i < size; i++)
{
printf("\nEnter amount taken in hour %d:", i + 1);
scanf("%f", &ary[i]);
}
ave = average(size, ary);
printf("\nThe average donated for %s is: %2.1f", dayOne, ave);
}
printf("\n\nEnter day that you want to see average donation amount for: ");
scanf("%s", dayTwo);
if(strcmp(dayOne, dayTwo)== 0)
printf("\nEnter a different day please: ");
scanf("%s", dayTwo);
{
float ary[size];
for (int i = 0; i < size; i++)
{
printf("\nEnter amount taken in hour %d:", i + 1);
scanf("%f", &ary[i]);
}
ave = average(size, ary);
printf("\nThe average donated for %s is: %2.1f", dayTwo, ave);
}
return 0;
}
double average(int size, float ary[])
{
double sum = 0;
double ave;
for (int i = 0; i < size; i++)
sum += ary[i];
ave = (double)sum / size;
return ave;
}
This is wrong:
int ary[7];
…
scanf("%f", &ary[i]);
%f is for scanning a float, but ary[i] is an int. The resulting behavior is not defined.
This is wrong:
double size;
…
ave = average(size, ary);
Nothing in the “…” assigns a value to size, so it has no defined value when average is called.
Quite a few syntactical and logical changes to be made buddy. As Eric Postpischil has mentioned in his answer, your size variable isn't initialized to anything before use. And using %f for accepting integers is incorrect too. Along with these, there are a few other glitches which I will list below, with the corresponding fixes. I have also attached the full working code along with the output.
Error: size variable not initialized.
Fix:: Since you have a fixed number of hours, you can either use the 7 directly or through size. Hence initialize the variable while declaring it. And just a suggestion buddy, use int for size. ==> int size = 7;
Error: Accepting input for array values. The array ary is of type int, but you have used %f which is a format specifier for float.
Fix: Use %d which is the format specifier for int data type. ==> scanf("%d", &ary[i]);
Error: Format specifier used for printing the average value. You have used %f again which is for float while the variable ave for average if of type double.
Fix: Use %lf which is the format specifier for double. ==> printf("\nThe average for the 2nd day is: %.3lf", ave); The .3 before lf is just to limit the number of decimal points to 3. It is optional.
Error: You accept the second day and display a message if it is the same as the first day, but the scanf for this is out of the if loop. hence it prompts the user to input another name of the day regardless of whether the second input day is same as the first or not.
Fix: just move that scanf into the if loop where you check if that day is same as the previous one.
I wouldn't really call this one an error, because it's just an improvement which I find that needs to be done. You accept the second day which should be different from the first with the message that average would be found. But you are not calculating the average for this day. Hence I have included that part in the code.
CODE:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
double average(int, int [7]);
int main(void)
{
char dayOne[8], dayTwo[8];
int size = 7;
double ave;
printf("Enter day that you want to see average donation amount for: ");
scanf("%s", dayOne);
int ary[7];
for (int i = 0; i < 7; i++)
{
printf("Enter amount taken in hour %d:", i + 1);
scanf("%d", &ary[i]);
}
ave = average(size, ary);
printf("\nThe average for the 1st day is: %.3lf", ave);
printf("\n\nEnter day that you want to see average donation amount for:");
scanf("%s", dayTwo);
if(strcmp(dayOne, dayTwo)== 0) {
printf("\nEnter a different day please: ");
scanf("%s", dayTwo);
}
for (int i = 0; i < 7; i++)
{
printf("Enter amount taken in hour %d:", i + 1);
scanf("%d", &ary[i]);
}
ave = average(size, ary);
printf("\nThe average for the 2nd day is: %.3lf", ave);
return 0;
}
double average(int size, int ary[7])
{
int sum = 0;
double ave;
for (int i = 0; i < size; i++) {
sum = sum + ary[i];
}
ave = sum / size;
return ave;
}
OUTPUT:
Enter day that you want to see average donation amount for: Day1
Enter amount taken in hour 1: 1
Enter amount taken in hour 2: 2
Enter amount taken in hour 3: 3
Enter amount taken in hour 4: 4
Enter amount taken in hour 5: 5
Enter amount taken in hour 6: 6
Enter amount taken in hour 7: 7
The average for the 1st day is: 4.000
Enter day that you want to see average donation amount for: Day2
Enter amount taken in hour 1: 8
Enter amount taken in hour 2: 8
Enter amount taken in hour 3: 8
Enter amount taken in hour 4: 8
Enter amount taken in hour 5: 8
Enter amount taken in hour 6: 8
Enter amount taken in hour 7: 8
The average for the 2nd day is: 8.000
Hope this helps.
double size;
The size variable has not been set before calling the average function.
ave = average(size, ary);
May be size can be initialized to 0 and incremented in the for loop as given below
double size = 0;
double ave;
printf("Enter day that you want to see average donation amount for: ");
scanf("%s", dayOne);
{
int ary[7];
for (int i = 0; i < 7; i++)
{
printf("Enter amount taken in hour %d:", i + 1);
scanf("%f", &ary[i]);
size++;
}
ave = average(size, ary);
printf("\nThe average for the day is: %f", ave);
}
If the goal is to receive user input as a double, the array used to hold those values should be double.
double ary[7];
instead of
int ary[7];

Incorrect output for a particular code. (Maximum, minimum, grade_scanner)

I've been trying to figure this out the last few days, but no luck. The objective is to find the sum, average, minimum, and maximum grades and display them.
Here is my code, everything except minimum, maximum and grade input seem to work
// Includes printf and scanf functions
#include <stdio.h>
int main(void) {
unsigned int counter; // number of grade to be entered next
int grade; // grade value
int total; // sum of grades entered by user
float average; // average of grades
int maxi; // Max grade
int mini; // min grade
int i;
int max;
int min;
maxi = 1;
mini = 1;
printf("Enter number of grades: "); // User enters number of grades
scanf("%d", &counter); // Countss number of grades
//scanf("%d%d", &min, &max);
for (i = 1; i <= counter; i++) {
printf("Enter grade %d: ", i); // User enters grade
scanf("%d", &grade); // Counts grades
//scanf("%d",&counter);
if (grade < 0 || grade > 100) {
printf("Please enter a number between 0 and 100!\n"); // Lets user know if input is invalid
i--;
break;
}
else {
total = total + grade;
average = (float)total / counter; // NOTE: integer division, not decimal
}
}
max = (grade < maxi) ? maxi : grade;
min = (grade > mini) ? mini : grade;
printf("Class average is: %.3f\n", average); // Displays average
printf("Your maximum grade is %d\n", max); // Displays Max
printf("Your minimum grade is %d\n", min); // Displays minimum
printf("Sum: %d\n", total); // Displays total
}
Output:
Enter number of grades: 2
5
7
Enter grade 1: 4
Enter grade 2: 3
Class average is: 3.500
Your maximum grade is 3
Your minimum grade is 1
Sum: 7
For some reason when I start the program, I have to enter a few numbers, in this case 5 & 7 before it prompts me to "Enter grade" then from there it calculates everything. Also, it seems that the Maximum is always the last grade that I enter and shows 1 as the minimum when no where in the input is 1. I am supposed to use a conditional operator for the max/min, I tried looking it up and reading the book, but they just use letters like a,b,c, etc. Which just confused me so I'm not sure if I did it wrong.
Could that be what is messing everything up? If it isn't what am I doing wrong?
Another thing is I'm thinking I need a While loop if I want to make the counter have an input from 1-100, is that right?
Edit: just realized I had to remove the scanf for max and min. Taht's why I had to inptu 2 nubmers first
There are two major problems, as I see it
The variable total is not initialized, so the first occurrence of total = total + grade; would invoke undefined behaviour.
You have to initialize it explicitly to 0.
The same variable grade is used for holding the repeated input. After the loop, grade will only hold the last input value.
You need to either use an array for storing inputs and comparison, or, compare and update the min and max as you go, inside the loop.
For future references, please seperate your code in different functions or add comments, since analyzing an unfamiliar code always takes much time.
min: Your problem here lies, that you're initializing your min value with 1. That value is most of the time below your input grades. If you want to initialize it, you should use a high number.
For example:
#include <limits.h>
int min = INT_MAX;
max: Your "grade" will be always the last typed grade, which you scanned. That's not what you want. It would be good, to save all values, which you get as input in an array or a list.
Also your codesnippet at the end
max = (grade<maxi) ? maxi : grade;
min = (grade>mini) ? mini : grade;
will just compare one grade. You need to compare all values, which you entered.
You could just put them in the for-loop.
gradeinput: You need to temporarily save your inputs in a datastructure like an array/list to use them in your program.
int x[counter];
for (i = 1; i <= counter; i++) {
printf("Enter grade %d: ", i);
x[i]=scanf("%d", &grade);
}
.. have to enter a few numbers, in this case 5 & 7 before it prompts me to "Enter grade"
This happens because OP's stdout is buffered and not one character at a time.
To insure output is seen before the scanf(), use fflush().
See What are the rules of automatic flushing stdout buffer in C?
printf("Enter number of grades: ");
fflush(stdout); // add
scanf("%d", &counter);
Rather than set the min = 1, set to a great value
maxi = 1;
mini = 1;
maxi = 0;
mini = 100;
// or
maxi = INT_MIN;
mini = INT_MAX;
Move the test for min/max in the loop to test each value and fold maxi, max into the same variable.
if (max > grade) max = grade;
if (min < grade) min = grade;
The first total + grade is a problem as total is uninitialized.
// int total; // sum of grades entered by user
int total = 0; // sum of grades entered by user
Unnecessary to calculate average each time though the loop. Sufficient to do so afterward.
Style: After the break; the else is not needed.
Good that code tests user input range. Yet the i-- is incorrect. If code is to break, just break. If code it to try again, the i-- makes sense, but then code should continue.
The comment // NOTE: integer division, not decimal is incorrect as (float) total / counter is FP division.
if (grade < 0 || grade > 100) {
printf("Please enter a number between 0 and 100!\n");
i--;
continue;
}
total = total + grade;
} // end for
average = (float) total / counter;
In general, casting should be avoided.
Advanced issue: Consider the situation if later on code was improved to handle a wider range of integers and used higher precision FP math.
The 1st form causes total to become a float (this could lose precision) and perhaps use float to calculate the quotient, even if average was a double. Of course the (float) cast could be edited to (double) as part of the upgrade, but that is a common failure about updates. Types may be changed, but their affected object uses are not fully vetted.
The 2nd form below causes total to become the same type as average and use the matching math for the type. Reduced changed needed as the types change. This form is also easier to review as one does not need to go back and check the FP type of average to see if a cast to float, double or even long double was needed.
average = (float) total / counter;
// or
average = total;
average /= counter;
For some reason when I start the program, I have to enter a few numbers, in this case 5 & 7 before it prompts me to "Enter grade"
You have two scanf before "Enter grade"
scanf("%d", &counter);
scanf("%d%d", &min, &max);
#include <stdio.h>
int main(void) {
int counter; // number of grade to be entered next
int grade; // grade value
int total=0; // sum of grades entered by user
float average; // average of grades
int i;
int max;
int min;
printf("Enter number of grades: "); // User enters number of grades
scanf("%d", &counter); // Countss number of grades
for (i = 1; i <= counter; i++) {
printf("Enter grade %d: ", i); // User enters grade
scanf("%d", &grade); // Counts grades
if (grade < 0 || grade > 100) {
printf("Please enter a number between 0 and 100!\n"); // Lets user know if input is invalid
i--;
} else {
if(i==1){
max = grade;
min = grade;
}
else{
max = (grade < max) ? max : grade;
min = (grade > min) ? min : grade;
}
total = total + grade;
average = (float) total / counter; // NOTE: integer division, not decimal
}
}
printf("Class average is: %.3f\n", average); // Displays average
printf("Your maximum grade is %d\n", max); // Displays Max
printf("Your minimum grade is %d\n", min); // Displays minimum
printf("Sum: %d\n", total); // Displays total
}
I've edited your Code as there were some mistakes. First, you were not initialising the total, which may make it take some garbage value. The second one is no need of using break as you are reducing the value of i.The third one is that you are updating the min and max outside the for loop, where the value of grade will be the last entered grade. And maxi and mini are not at all needed. The code was running perfectly without waiting for dummy values. Cheers!

show decimal using C

I'm trying to show the decimal points after the number
#include <stdio.h>
int main() {
int weight;
int miles;
int price;
printf("Enter the packages weight \n");
scanf("%d", &weight);
printf("Enter how many miles to ship the package \n");
scanf("%d", &miles);
if(weight <= 15) {
price = 15;
}
else {
price = (15 + ((weight - 15) * .5 ));
}
if(miles % 500 == 0) {
price += (miles / 500 * 10);
}
else {
price += ((miles / 500 )* 10) + 10;
}
printf("It will cost $%d to ship an item weighing %d pounds %d miles \n", price, weight, miles);
return 0;
}
for the price = (15+((weight-15)*.5)); When I plug in the numbers outside of the console it shows the decimal places. I'm probably missing the most simple thing...
You should change the data type of the variable price to float (or double) if you wish to store some fractional part in it.
Also, since miles / 500 may create some decimal part (and miles itself can be floating-point!), it should also be made float or double.
Finally, in the printf arguments, do not forget to change the format specifier %d.
Prefer to use a floating-point data type for all the variables involved in some computation that might yield fractional numbers as it will be more comprehensible and if you wish to not see the decimal part in the output, then set the precision to 0 (%.0f).

Resources