I am trying to make a loop where I enter 30 or less student's GPA and get: the average gpa, highest and lowest gpa, adjusted average, see if a specific gpa was entered and display the contents of the array. But when I run the code I have, I can only enter one gpa...
#include <stdio.h>
#include <stdlib.h>
#define GPA_COUNT 30
main(){
int gpa [GPA_COUNT];
int total = 0, i;
double average;
for(i = 0; i < GPA_COUNT; i++){
printf("Enter student %i's GPA: \n", i + 1);
scanf("%i", &gpa[i]);
}
for(i = 0; i < GPA_COUNT; i++){
total += gpa[i];
if(gpa[i] > 2.0){
printf("You need to study harder! \n");
}
else if(gpa[i] < 3.5){
printf("Nice work! \n");
}
}
average = (double)total / GPA_COUNT;
printf("The average GPA is: %.2lf \n", average);
system("pause");
}
I would like to be able to enter the rest of the gpa's.
As Antii Haapala says in his comment, your problem is that you've initialized gpa as an integer, and are using printf to scan in an integer -- but are actually entering a double.
To fix it, you simply need to expect a double instead:
double gpa [GPA_COUNT];
// -- snip --
scanf("%lf", &gpa[i]);
I'm assuming you're a student, so here are a couple of other notes to help you improve your code:
Take a look at your conditional when checking the student's GPA (what happens if a student scores a 1.0? A 4.0?)
You can remove the \n from this line (printf("Enter student %i's GPA: \n" i + 1);) to have the inputs on the same line.
Consider what will happen if someone throws garbage input at your program -- sanitizing user inputs is important! A safer, but still simple, method would be to read the user input as a string, and then attempt to convert the input with something like strtod.
Related
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];
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!
I'm coding in c and have been attempting to make an average calculator, as i am new to coding and only just starting and my code won't work after i input a number for it. the way it should work is you input a number, the code keeps track of the overall number and the amount of numbers entered and prints out the average, doing this all in "do while" loop
my code:
int main()
{
float overall = 0;
float entered = 0;
float times = 0;
float avg = 0;
printf("AVERAGE CALULATOR\n\npress 0 when complete\n\n");
do{
printf("current average: %.2f\n\n", avg);
printf("input number: ");
scanf("%f", entered);
overall += entered;
times++;
avg = overall / times;
}while(entered != 0);
return 0;
}
pleae inform me of incorrect code if you find it
You just forgot the (&) in scanf after the comma.
scanf("%f", &entered);
Scanf needs a pointer to your adress.
Alright so I've having trouble on the next step of my c program. Basically, it is a database that accepts user input and then uses a switch-statement to retrieve or calculate the individual or group statistics. Note that:
A student whose EUID (roll number) is stored in location i of the EUID array will have his or her homework average, exam 1 grade, and exam 2 grade stored in location i of the appropriate arrays.
So far the code is able to run but I'm stumped when it comes to the switch statement.
I only really need advice on the first case of the switch statement but included the rest just in case.
In short for case 1, how can I get the program to print out a student's grades and average using a specific EUID. The output should look something like this:
1
Please enter student EUID:
1893839
EUID: 1893839 Homework: 84.34 Exam 1: 84 Exam 2: 76
Here's what I have so far:
#include <stdio.h>
#include <math.h>
struct Grade
{
int euid;
double hwavg;
double exam1;
double exam2;
};
int main()
{
struct Grade record[200];
int input, i;
printf("Input each student's EUID, homework average, exam 1 grade, and exam 2 grade: \n\n");
printf("To terminate input '-1' as the student EUID, along with throwaway values for the average and grades.");
for(i=0; i<200; ++i)
{
scanf("%d %lf %lf %lf", &record[i].euid, &record[i].hwavg, &record[i].exam1, &record[i].exam2);
if(record[i].euid == -1)
{
break;
}
}
while(1)
{
printf("Select one of the following:\n 1. Student grade data \n 2. Student grade average \n 3. Class average for assignment \n 4. Exit\n");
scanf("%d\n",&input);
switch(input)
{
case 1:
printf("Enter the student's EUID:\n");
/*The output here should be the EUID, homework avgerage, exam 1 grade and exam 2 grade. */
break;
case 2:
printf("Enter the student's EUID:\n");
/*Finds and prints the the students average and letter grade. */
/* (HW * 0.5) + (EXAM1 * 0.25) + (EXAM2 * 0.25) */
break;
case 3:
/* Finds total class average. */
break:
case 4:
printf("Terminating program: Bye-bye!\n");
return 0;
break;
default:
printf("Error! Invalid input.\n\n");
}
}
}
Basically, it seems what you're looking for is something along the line...
printf("EUID:%d Homework: %.2f Exam 1:%.0f Exam2: %.0f\n", record[i].euid, record[i].hwavg, record[i].exam1, record[1].exam2);
Note: The %.0f makes an output of 0 decimals.
In order to calculate the average, this can be done in your first for-loop, which reads and fills in the array.
You may want to search the net for "printf double"; here's an example reference.
-What I almost never see mentioned is that you can choose argument numbers using %2$f (where 2 denotes argument number 2).
To find the index of the EUID, you could use something like this:
i = 0;
while(record[i].euid != -1 && record[i].euid != euid)
{
i++;
}
-You'll of course need to scanf to get the euid.
I tried to search this everywhere, but it's kind of difficult to word, it's most likely a simple fix. Basically when I go through my program that is supposed to compute the average rainfall for a year, it comes out with a very large number, however, I thought it may have been just that I was doing the arithmetic wrong or had a syntax error of some sort, but that was not the case, when I checked the value that the function returned it was the proper value.
#include <stdio.h>
#include <string.h>
void getData(float *, float *);
int main()
{
char state[2], city[81];
float rainFall[12], outputAverage, *pAverage;
printf("Name Here\n");
printf("Please enter the state using a two letter abreviation: ");
gets(state);
printf("Please enter the city : ");
gets(city);
pAverage = &outputAverage;
(getData(rainFall, pAverage));
printf("%.2f", outputAverage);
return (0);
}
void getData(float *rainFall, float *pAverage)
{
int i;
float total;
for (i=0; i<12; i++)
{
printf("Please enter the total rainfall in inches for month %d: ", i+1);
scanf("%f", &rainFall[i]);
total += rainFall[i];
}
*pAverage = total / 12;
}
you need to initialize total
float total = 0.0;
Initialize the total to 0
Why you make it complicated? Why not just
return total / 12 ?
and called it like
outputAverage = getData(rainfall)
This is a classic problem in C programming. You are mixing strings and numbers on the input. You are better off reading the input into a string and then, using sscanf to parse it properly.
You have uninitialized variable total which is taking garbage value, thus you see a very large answer.
changed your main.. have a look and let me know if you have understood what changes i have made?
#include <stdio.h>
#include <string.h>
void getData(float *);
int main(int argc, char*argv[])
{
char state[3]={0}, city[81]={0};
float outputAverage;
printf("Name Here\nPlease enter the state using a two letter abreviation: ");
scanf("%s",state);
printf("Please enter the city : ");
scanf("%s",city);
getData(&outputAverage);
printf("The Average Rainfall recorded for the year is %.2f\n", outputAverage);
return 0;
}
void getData(float *pAverage)
{
int i;
float rainFall[12]={0}, total=0;
for (i=0; i<12; i++)
{
printf("Please enter the total rainfall in inches for month %d: ", i+1);
scanf("%f", &rainFall[i]);
total += rainFall[i];
}
*pAverage = total / 12;
}
However instead of using gets you should use fgets but i forgot how to counter the issue of using simultaneous fgets to read input from the standard input stream.
Also initialize the total variable as you are adding in the loop new values to existing value in that variable which would not necessarily add to zero as the premier element. so it could be any garbage value + loop values.
I understand you are practicing pointer concept so you passed the address of the array of floats to your second function but if the rainfall function is not useful in main, Better to restrict the same where it would be useful