Average of an arbitrary amount of numbers - c

I'm currently trying to create a C program for a class assignment that takes the average of an arbitrary amount of test scores. However, I've run into some problems.
My professor has provided an outline to help get started. I also can only add code where indicated, so no extra variables and such.
This is what I have so far:
#include <stdio.h>
void calculateAverage()
{
int grade, count, sum;
double average;
/* add code to input grades, calculate average, and print it */
/* --> between here */
printf("Enter the amount of test scores.\n");
scanf("%d", &count);
grade = 0;
sum = 0;
while (grade != -1 && grade <= 100 && grade >= 0)
{
printf("Enter the grade. Enter -1 when you are done entering grades.\n");
scanf("%d", &grade);
if (grade != -1 && grade <= 100 && grade >= 0)
{
sum = sum + grade;
}
else
{
average = (sum / count);
printf("average is %.2lf \n", &average);
}
}
/* --> and here */
}
int main(void)
{
while (1)
calculateAverage();
return 0;
}
So the problem I've ran into is that with what I have so far, the average will always be calculated as 0. Why exactly is this happening, and how would I fix it so it gives me the correct average?
UPDATE
So I tried casting the average to double so I can avoid a type mismatch, which did get rid of my compiler warnings but the average is still coming out to 0 for all inputed values.
#include <stdio.h>
void calculateAverage()
{
int grade, count, sum;
double average;
/* add code to input grades, calculate average, and print it */
/* --> between here */
printf("Enter the amount of test scores.\n");
scanf("%d", &count);
grade = 0;
sum = 0;
while (grade != -1 && grade <= 100 && grade >= 0)
{
printf("Enter the grade. Enter -1 when you are done entering grades.\n");
scanf("%d", &grade);
if (grade != -1 && grade <= 100 && grade >= 0)
{
sum = sum + grade;
}
else
{
average = (double)(sum / count);
printf("average is %.2f \n", &average);
}
}
/* --> and here */
}
int main(void)
{
while (1)
calculateAverage();
return 0;
}

#include <stdio.h>
void calculateAverage()
{
int grade, count, sum;
double average;
/* add code to input grades, calculate average, and print it */
/* --> between here */
printf("Enter the amount of test scores.\n");
scanf("%d", &count);
grade = 0;
sum = 0;
while (grade != -1 && grade <= 100 && grade >= 0)
{
printf("Enter the grade. Enter -1 when you are done entering grades.\n");
scanf("%d", &grade);
if (grade != -1 && grade <= 100 && grade >= 0)
{
sum = sum + grade;
}
else
{
average = (double)(sum / count);
printf("average is %.2lf \n", average); # <---- Please fix this!
}
}
/* --> and here */
}
int main(void)
{
while (1)
calculateAverage();
return 0;
}
There are a few problems in your code:
One is you are printing the address of average using & operator.
Another thing you can change is to use the correct format specifier when printing double.

Related

how not to get an extra count in a while loop?

I have the following code and every time i run it, I get an extra count. Say for example that I input 8 first round and then a 2 next round and exit with the sentinel -1, the sum will be 10 as expected, but the count will be 3. I've debugged the program and no matter if count comes before the scanf() or after, I still get a 3 value. One possible solution is to initialized count to -1. However, I feel I shouldn't have to and setting count equal to zero should work. Do I have to set count to -1?
#include <stdio.h>
void calculateAverage()
{
int grade = 0, count, sum = 0;
double average;
count = 0;
while(grade != -1)
{
sum += grade;
count++;
printf("input a grade: \n");
scanf("%d", &grade);
}
average = (double)(sum)/(double)(count);
printf("%.2lf", average);
return;
}
int main( )
{
while (1)
calculateAverage();
return 0;
}
For starters there is no great sense to declare the variable sum as having the type int because in any case you are casting it to the type double
average = (double)(sum)/(double)(count);
You are increasing the variable count before the user will enter something.
The function can be defined the following way as it is shown in the demonstrative program below.
#include <stdio.h>
void calculateAverage( void )
{
const int Sentinel = -1;
size_t count = 0;
double sum = 0.0;
printf( "input a grade (%d - stop): ", Sentinel );
for ( int grade; scanf( "%d", &grade ) == 1 && grade != Sentinel; )
{
sum += grade;
++count;
printf( "input a grade (%d - stop): ", Sentinel );
}
double average = count == 0 ? sum : sum / count;
printf( "%.2lf", average );
}
int main(void)
{
calculateAverage();
return 0;
}
The program output might look like
input a grade (-1 - stop): 1
input a grade (-1 - stop): 2
input a grade (-1 - stop): 3
input a grade (-1 - stop): 4
input a grade (-1 - stop): 5
input a grade (-1 - stop): 6
input a grade (-1 - stop): 7
input a grade (-1 - stop): 8
input a grade (-1 - stop): 9
input a grade (-1 - stop): 10
input a grade (-1 - stop): -1
5.50
You are incrementing count just before you enter -1. So, it counts -1 as well. Just in increase is if it's not -1.
#include <stdio.h>
void calculateAverage()
{
int grade = 0, count = 0, sum = 0;
double average;
while (grade != -1)
{
sum += grade;
printf("input a grade (-1 - stop): ");
scanf("%d", &grade);
if (grade != -1) // Check this line
count++;
}
average = (double)sum / count;
printf("%.2lf\n", average, sum, count);
return;
}
int main()
{
while (1)
calculateAverage();
return 0;
}

C Programming - Getting the Median from User Inputs

I need help fixing my code. What my code does it asking users to input a number multiple times and will terminate the program once -1 is entered. Then, will get the Sum, Max, Min, Average and Median values.
Sum, Min and Max seems to be working fine. But on the "Average" it's treating the -1 as a userinput, also, I need help on how to get the median value.
Here's what I got so far.
#include <stdio.h>
int main(){
char name[30];
int userInput;
int count = 0;
int sum = 0; // changed from 1 to 0
int max, min = 1000;
float average;
printf("Please enter your name: ");
scanf("%s", &name);
printf("Hello, %s, ", name);
do {
printf("Enter an integer (-1 to quit): ");
scanf("%d", &userInput);
if (userInput == -1) break; // I added this line, average works fine now
sum = sum + userInput;
count = count + 1;
average = sum / count;
if (userInput > max){
max = userInput;
}
if (userInput < min && userInput >= 0){
min = userInput;
}
}
while (userInput >= 0);
printf("Sum: %d \n", sum);
printf("Average: %.2f \n", average);
printf("Max: %d \n", max);
printf("Min: %d \n", min);
return 0;
}
Here's my sample output:
Please enter your name: A
Hello, A, Enter an integer (-1 to quit): 10
Enter an integer (-1 to quit): 20
Enter an integer (-1 to quit): 10
Enter an integer (-1 to quit): -1
Sum: 40
Average: 10.00
Max: 20
Min: 10
So The rest seems to be working now after some modification except for getting the median value.
You do not want to increment the count when userInput == -1
You're incrementing the count and adding to the sum before checking whether userInput == -1. Try rewriting your loop:
while(1){
printf("Enter an integer (-1 to quit): ");
scanf("%d", &userInput);
if(userInput == -1)
break;
/* rest of loop body goes here */
}

C Program Limit the integer input range

I am a new C programming learner, I am trying to make a program which would calculate the GPA of a student on the basis of grade marks input and credits of a subject.
The problem I am having is I want to limit the number of subjects input from 2 to 6 only.
Another problem is I want to limit the user to input integer from 1 to 100 only, instead of any other keywords, special characters (EOF)
I have put the "###" in comment line where I require these modifications.
#include <stdio.h>
int main(void) {
// input user input -- hopefully a number
// temp used to collect garbage characters
// status did the user enter a number?
// counter for keeping track of loop repetition
// no no. of subjects to be entered by user.
// credits credits per subject
// grades grades acheived in each subject (1 to 100).
// grade_value for holding the value of each subject grade (for ex; 80 to hundred is 4.0)
// grade_points Grade points for each subject (credits * grade_value)
// sum sum of total grade points
int counter = 1, subjects, no, credits, grades, status, temp;
float grade_value, grade_point, sum;
printf("Enter number of subjects you took for current semester: ");
status = scanf("%d", & no);
// ### I want to limit this integer input to be >=2 && <=6.
while (status != 1) {
while ((temp = getchar()) != EOF && temp != '\n');
if ((temp < 2) && (temp > 6));
break;
printf("Invalid input... please enter the number of subject again: ");
status = scanf("%d", & no);
}
// ### I want to be this input to block other character inputs than integer from 1 to hundred.
while (counter <= no) {
printf("\nEnter Subject %d grades separated with credits \n", counter);
scanf("%d %d", & grades, & credits);
if ((grades > 0) && (grades <= 29)) {
grade_value = 0;
printf("Grade value for subject %d is: %.2f", counter, grade_value);
grade_point = credits * grade_value;
printf("\nGrade point for subject %d is: %.2f", counter, grade_point);
sum = sum + grade_point;
++counter;
} else if ((grades >= 30) && (grades <= 34)) {
grade_value = 0.67;
printf("Grade value for subject %d is: %.2f", counter, grade_value);
grade_point = credits * grade_value;
printf("\nGrade point for subject %d is: %.2f", counter, grade_point);
sum = sum + grade_point;
++counter;
} else if ((grades >= 35) && (grades <= 39)) {
grade_value = 1;
printf("Grade value for subject %d is: %.2f", counter, grade_value);
grade_point = credits * grade_value;
printf("\nGrade point for subject %d is: %.2f", counter, grade_point);
sum = sum + grade_point;
++counter;
} else if ((grades >= 40) && (grades <= 44)) {
grade_value = 1.33;
printf("Grade value for subject %d is: %.2f", counter, grade_value);
grade_point = credits * grade_value;
printf("\nGrade point for subject %d is: %.2f", counter, grade_point);
sum = sum + grade_point;
++counter;
} else if ((grades >= 45) && (grades <= 49)) {
grade_value = 1.67;
printf("Grade value for subject %d is: %.2f", counter, grade_value);
grade_point = credits * grade_value;
printf(" \nGrade point for subject %d is: %.2f", counter, grade_point);
sum = sum + grade_point;
++counter;
} else if ((grades >= 50) && (grades <= 54)) {
grade_value = 2;
printf("Grade value for subject %d is: %.2f", counter, grade_value);
grade_point = credits * grade_value;
printf("\nGrade point for subject %d is: %.2f", counter, grade_point);
sum = sum + grade_point;
++counter;
} else if ((grades >= 55) && (grades <= 59)) {
grade_value = 2.33;
printf("Grade value for subject %d is: %.2f", counter, grade_value);
grade_point = credits * grade_value;
printf("\nGrade point for subject %d is: %.2f", counter, grade_point);
sum = sum + grade_point;
++counter;
} else if ((grades >= 60) && (grades <= 64)) {
grade_value = 2.67;
printf("Grade value for subject %d is: %.2f", counter, grade_value);
grade_point = credits * grade_value;
printf("\nGrade point for subject %d is: %.2f", counter, grade_point);
sum = sum + grade_point;
++counter;
} else if ((grades >= 65) && (grades <= 69)) {
grade_value = 3;
printf("Grade value for subject %d is: %.2f", counter, grade_value);
grade_point = credits * grade_value;
printf("\nGrade point for subject %d is: %.2f", counter, grade_point);
sum = sum + grade_point;
++counter;
} else if ((grades >= 70) && (grades <= 74)) {
grade_value = 3.33;
printf("Grade value for subject %d is: %.2f", counter, grade_value);
grade_point = credits * grade_value;
printf("\nGrade point for subject %d is: %.2f", counter, grade_point);
sum = sum + grade_point;
++counter;
} else if ((grades >= 75) && (grades <= 79)) {
grade_value = 3.67;
printf("Grade value for subject %d is: %.2f", counter, grade_value);
grade_point = credits * grade_value;
printf("\nGrade point for subject %d is: %.2f", counter, grade_point);
sum = sum + grade_point;
++counter;
} else if ((grades >= 80) && (grades <= 100)) {
grade_value = 4;
printf("Grade value for subject %d is: %.2f", counter, grade_value);
grade_point = credits * grade_value;
printf("\nGrade point for subject %d is: %.2f", counter, grade_point);
sum = sum + grade_point;
++counter;
}
// To print a message if user doesnt enter an integer varying from 1 to 100.
else {
printf("\n Error Grade input, Please Key in Again. (1 to 100 only.)");
}
}
printf("\n");
printf("\n");
printf("\nThe GPA is: %.2f", sum);
if (sum <= 49) {
printf("\nYou can register for 2 subjects for next semester.");
} else if ((sum >= 50) && (sum >= 79)) {
printf("\nYou can register for 5 subjects for next semester.");
} else if ((sum >= 80) && (sum <= 100)) {
printf("\nYou can register for 6 subjects for next semester.");
}
printf("\n");
printf("\n");
printf("\n_______________________________________________________");
printf("\nEnd of program");
return 0;
}
A do-while loop is perfect for loops that need to be called at least once and will get rid of your duplicated code. Reading unstructured input, possibly from the keyboard, (one could call, ./a.out < text.txt,) is actually something that is tricky to get right.
Luckily, the C FAQ has lots of advice, eg, http://c-faq.com/stdio/scanfprobs.html. It's going to be very arduous without functions, though. From limited testing, I'm pretty sure that this is a solid way to read the first variable.
#include <stdio.h> /* fgets sscanf */
#include <stdlib.h> /* EXIT_ printf fprintf */
#include <string.h> /* strlen */
int main(void) {
int no;
/* Input number, no \in [2, 6], and make sure that the read cursor is on
the next line. */
do {
char buffer[80];
size_t len;
printf("Enter number of subjects you took for current semester, [2, 6]: ");
/* On the advice of http://c-faq.com/stdio/scanfprobs.html, this reads
into a buffer first. */
if(!fgets(buffer, sizeof buffer, stdin)) {
if(feof(stdin)) {
fprintf(stderr, "Premature EOF.\n");
} else {
/* On IEEE Std 1003.1-2001-conforming systems, this will print
a meaningful error. */
perror("stdin");
}
/* Can't really do anything interactive once stdin has a read
error. */
return EXIT_FAILURE;
}
/* This is always going to be true, but segfaults if not. Paranoid. */
if(!(len = strlen(buffer))) continue;
/* Normally fgets stores a '\n' at the end; check. */
if(buffer[len - 1] != '\n') {
/* Check if the length of the buffer is big enough to hold input. */
if(len >= sizeof buffer - 1) {
int c;
fprintf(stderr, "Line too long.\n");
/* Flush whole line. http://c-faq.com/stdio/stdinflush2.html */
while((c = getchar()) != '\n') {
if(c != EOF) continue;
if(feof(stdin)) fprintf(stderr, "Premature EOF.\n");
else perror("stdin");
return EXIT_FAILURE;
}
continue;
} else {
/* Non-POSIX lines, eg, file without '\n' terminating. */
fprintf(stderr, "Note: line without line break detected.\n");
}
}
/* Parse buffer for a number that's between [2, 6]. Ignore the rest. */
if(sscanf(buffer, "%d", &no) != 1 || no < 2 || no > 6) {
fprintf(stderr, "Invalid input.\n");
continue;
}
/* Now no \in [2, 6]. */
printf("no: %d\n", no);
break;
} while(1);
return EXIT_SUCCESS;
}
One may be able to get away with a subset of this if your teacher enters only well-formed numbers.
Your code has some semantic mistakes. You must never put a semicolon after a if statement. Also you can write a more legible code by spacing blocks of code. Even better, you could refactor some blocks and encapsulate it into functions. Aside of that, see this solutions:
For the first problem, it can be solved with few lines of code. It's a good practice that the user know the restrictions of inputs before enter his input:
/* ### I want to limit this integer input to be >=2 && <=6. */
#include <stdio.h>
int main()
{
int no;
do {
printf("Enter number of subjects you took for current semester (2~6): ");
scanf("%d", &no);
} while (no < 2 || no > 6);
return 0;
}
The other issue can be solved by using the Standard C Library. Just #include <string.h> and #include <ctype.h>
#include <stdio.h>
#include <string.h> /* strlen() */
#include <ctype.h> /* isdigit() */
int main()
{
int n, invalidInput, status;
char strInput[5];
int i; /* for loop */
do {
invalidInput = 0;
printf("Enter a **number** between 1 and 100: ");
fflush(stdin);
status = scanf("%4s", strInput); /* read at maximum 4 chars from stdin */
if (status > 3) {
continue; /* try again */
}
for (i = 0; i < strlen(strInput); ++i) { /* ensure that all characters are numbers */
if (!isdigit(strInput[i])) {
invalidInput = 1;
break;
}
}
if (!invalidInput) {
n = atoi(strInput); /* now your input is a integer */
if (n < 1 || n > 100) {
printf("Error: the input must be between 1 and 100.\n");
invalidInput = 1;
}
}
} while (invalidInput); /* repeat until all chars are digits and they are in the required interval */
return 0;
}

for/while loop memory clearing in C

In my program I'm messing around with, it simply asks for how many tests one has written and then returns an average. However I've modified it a bit so that it asks if the marks entered are correct.
Problem 1: It doesn't let you input your marks for all your tests
Problem 2: If the marks are wrong it starts over but keep the previous inputs in it's memory? How do I fix the?
Here's the code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
//int variables for grade
unsigned int counter; //number of grades to be entered next
int grade;
int total;
float average;
// user input
int userInput; // amount of tests
int yesNo;
//amount of test passed
unsigned int pass = 0;
unsigned int fail = 0;
int doCount = 1;
//unsigned int test;
//---------------------------------------------------------------------------------------------------//
//standards for program to abide to
total = 0; //Total amount of test to be set to zero, until while statement
counter = 1; //Loop counter to start from one
//---------------------------------------------------------------------------------------------------//
printf ("Please enter amount of test you've written so far: ");
scanf ("%d", &userInput);
//printf ("%d", userInput);
//---------------------------------------------------------------------------------------------------//
do {
//Body of calculations of program
for(counter = 0; counter <= userInput; ++counter) { //for loop that correlates to userInput for amount of passes and test marks
printf ("Please enter percentage mark: "); //prompt for test mark
scanf("%d", &grade);
total = total + grade;
counter = counter + 1;
if (grade >= 40) { //if statement for pass or fail
pass = pass + 1;
} else {
fail = fail + 1;
}
}//end of for loop
printf ("Are the grades entered correct? (1 = yes, 2 = no): "); // user input for yesNo - are inputs correct
scanf ("%d", &yesNo);
if (yesNo == 2) {
} else {
average = ((float)total / userInput); //Getting average for tests so far
//if statement to clarify if you're passing
if (average < 40) {
printf ("\nYou are below sub minimum!\n");
printf ("Your overall average is: %.2f %\n", average);
printf ("Passed: %d\n", pass);
printf ("Failed: %d", fail);
} else if (average >= 75){
printf ("\nYou have a distinction agregate!\n");
printf ("Your overall average is: %.2f %\n", average);
printf ("Passed: %d\n", pass);
printf ("Failed: %d", fail);
} else {
printf ("\nYour overall average is: %.2f %\n", average);
printf ("Passed: %d\n", pass);
printf ("Failed: %d", fail);
}
doCount = 2;
}
} while (doCount == 1);
average = ((float)total / userInput); //Getting average for tests so far
//---------------------------------------------------------------------------------------------------//
getch ();
return 0;
}
In your do while loop, when you come around for your second pass you need to reset your variables. Specifically the total variable should be reset to zero. You do it for the first time outside the do while loop but once it's in the loop for the second pass it doesn't get reset to 0.
As for not reading all test inputs, if it asks for 9 but you need 10 then it likely is a problem with the for loop. I typically use counter++ and not ++counter as it increments the counter after the operation and not before the operation. That may or may not be the reason as I did not run your code, but it is worth looking at.
I've edited your code and commented the changes:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
//int variables for grade
unsigned int counter; //number of grades to be entered next
int grade;
int total;
float average;
// user input
int userInput; // amount of tests
int yesNo;
//amount of test passed
unsigned int pass = 0;
unsigned int fail = 0;
int doCount = 1;
//unsigned int test;
//---------------------------------------------------------------------------------------------------//
//standards for program to abide to
total = 0; //Total amount of test to be set to zero, until while statement
counter = 0; //Loop counter to start from zero, It's always better to start from zero
//---------------------------------------------------------------------------------------------------//
printf("Please enter amount of test you've written so far: ");
scanf("%d", &userInput);
//printf ("%d", userInput);
//---------------------------------------------------------------------------------------------------//
do {
//Body of calculations of program
total = 0; //You need to reset total pass and fail
pass = 0;
fail = 0;
for (counter = 0; counter < userInput; ++counter) { //for loop that correlates to userInput for amount of passes and test marks
printf("Please enter percentage mark: "); //prompt for test mark
scanf("%d", &grade);
total = total + grade;
//counter = counter + 1; You DON't need that
if (grade >= 40) { //if statement for pass or fail
pass = pass + 1;
}
else {
fail = fail + 1;
}
}//end of for loop
printf("Are the grades entered correct? (1 = yes, 2 = no): "); // user input for yesNo - are inputs correct
scanf("%d", &yesNo);
if (yesNo == 2) {
}
else {
average = ((float)total / userInput); //Getting average for tests so far
//if statement to clarify if you're passing
if (average < 40) {
printf("\nYou are below sub minimum!\n");
printf("Your overall average is: %.2f %\n", average);
printf("Passed: %d\n", pass);
printf("Failed: %d", fail);
}
else if (average >= 75) {
printf("\nYou have a distinction agregate!\n");
printf("Your overall average is: %.2f %\n", average);
printf("Passed: %d\n", pass);
printf("Failed: %d", fail);
}
else {
printf("\nYour overall average is: %.2f %\n", average);
printf("Passed: %d\n", pass);
printf("Failed: %d", fail);
}
doCount = 2;
}
} while (doCount == 1);
average = ((float)total / userInput); //Getting average for tests so far
//---------------------------------------------------------------------------------------------------//
getch();
return 0;
}

C Program that counts how many pass or fail grades and exits when a negative number is inputted

I'm a newbie to C Programming and we're still starting on the loops. For our exercise today, we were tasked to create a do-while program that counts how many pass and fail grades there are but the loop breaks when a negative number is inputted. Also, numbers above 100 is skipped. This is my program:
#include<stdio.h>
#include<conio.h>
int main()
{
int grade, pass, fail;
pass = 0;
fail = 0;
do {
printf("Enter grade:\n");
scanf("%d", &grade);
printf("Enter -1 to end loop");
}
while(grade == -1){
if(grade < 100){
if(grade >= 50){
pass = pass + 1;
}
else if {
fail = fail + 1;
}
}
break;
}
printf("Pass: %d", pass);
printf("Fail: %d", fail);
getch ();
return 0;
}
Can someone please tell me how to improve or where I went wrong?
You need to put all of the code that you loop between the do and the while statements.
do {
printf("Enter -1 to end loop");
printf("Enter grade:\n");
scanf("%d", &grade);
if(grade <= 100 && grade >= 0) {
if(grade >= 50){
pass = pass + 1;
}
else {
fail = fail + 1;
}
}
} while(grade >= 0);
The general structure of a do-while loop is:
do {
// all of the code in the loop goes here
} while (condition);
// <-- everything from here onwards is outside the loop
#include <stdio.h>
#include <conio.h>
int main()
{
int grade, pass, fail;
pass = 0;
fail = 0;
do {
printf("\nEnter grade:\n");
scanf("%d", &grade);
printf("Enter -1 to end loop");
if (grade < 100 && grade >= 50)
pass = pass + 1;
else
fail = fail + 1;
printf("\nPass: %d", pass);
printf("\nFail: %d", fail);
}
while (grade >= 0);
getch();
}
do {
// stuff
}
while {
// more stuff
}
Is mixing 2 concepts together: the while loop and the do while loop - I'd start by refactoring that piece.
The logic for your problem is:
Keep running while the input is not -1. If input is -1, break/exit execution and display output.
Enter grade.
If the grade is less than or equal to 100 or greater than or equal to 0 perform pass/fail checks:
If the grade is greater than or equal to 50, that person has passed. Increment the number of passes.
If the grade is less than 50, that person has failed. Increment the number of failed exams.
jh314's layout logic is correct, but doesn't fix the execution logic:
int grade, pass, fail;
pass = 0;
fail = 0;
do {
printf("Enter -1 to end loop");
printf("Enter grade:\n");
scanf("%d", &grade);
//you want grades that are both less than or equal to 100
//and greater than or equal to 0
if(grade <= 100 && grade >= 0){
if(grade >= 50){
pass = pass + 1;
}
//if the grades are less than 50, that person has failed.
else {
fail = fail + 1;
}
}
} while(grade != -1);
printf("Pass: %d", pass);
printf("Fail: %d", fail);

Resources