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;
}
Related
Trying to make a GPA calculator.
Here is my code:
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main()
{
float fgpa, grade, n;
char reply;
n = 1;
grade = 1;
printf("--- GPA Calculator ---");
while(fgpa < 1 || fgpa > 4)
{
printf("\n\nEnter your current GPA: ");
scanf("%f", &fgpa);
if(fgpa < 1 || fgpa > 4)
printf("Invalid Input! Please re-enter value.");
}
printf("\nUsing the following table to convert grade to points\n\nA+ = 4.0\nA = 4.0\nB+ = 3.5\nB = 3\nC+ = 2.5\nC = 2.0\nD+ = 1.5\nD = 1\nF = 0\n");
while(grade > 0, n++)
{
printf("\nEnter points for module %.0f, enter \"0\" if there are no more additional modules: ", n);
scanf("%f", &grade);
printf("%f", grade);
fgpa = (fgpa + grade) / n;
}
fgpa = fgpa* n / (n-1);
n--;
printf("\n\nNumber of modules taken: %.0f\nFinal GPA: %.1f", n, fgpa);
return 0;
}
I've tried using if(grade = 0) break; but its still not breaking the loop even when the grade is correctly read 0.
picture of 0 being read correctly but loop still continuing
There are multiple problems in the code:
fgpa is uninitialized so the first test in the loop has undefined behavior.
you should also test the return value of scanf() to detect invalid or missing input.
while (grade > 0, n++) is incorrect too: you should instead always read the next grade and test its value and break from the loop before incrementing n.
Your averaging method seems incorrect too: you do not give the same weight to every module.
It seems more appropriate for your purpose to use for ever loops (for (;;)), unconditionally read input, check for scanf() success and test the input values explicitly before proceeding with the computations.
Here is a modified version:
#include <stdio.h>
// flush the rest of the input line, return EOF at end of file
int flush(void) {
int c;
while ((c = getchar()) != EOF && c != \n')
continue;
return c;
}
int main() {
float fgpa;
float grade;
int n = 1;
char reply;
printf("--- GPA Calculator ---");
for (;;) {
printf("\n\nEnter your current GPA: ");
if (scanf("%f", &fgpa) == 1) {
if (fgpa >= 1 && fgpa <= 4)
break;
}
} else {
if (flush() == EOF) {
fprintf(stderr, "unexpected end of file\n");
return 1;
}
}
printf("Invalid Input! Please re-enter value.\n");
}
printf("\nUsing the following table to convert grade to points\n\n"
"A+ = 4.0\nA = 4.0\nB+ = 3.5\nB = 3\nC+ = 2.5\n"
"C = 2.0\nD+ = 1.5\nD = 1\nF = 0\n");
for (;;) {
printf("\nEnter points for module %d, enter \"0\" if there are no more additional modules: ", n);
if (scanf("%f", &grade) == 1) {
if (grade <= 0)
break;
printf("%f\n", grade);
fgpa = fgpa + grade;
n = n + 1;
} else {
if (flush() == EOF)
break;
printf("Invalid Input! Please re-enter value.\n");
}
}
fgpa = fgpa / n;
printf("\n\nNumber of modules taken: %d\nFinal GPA: %.3f\n", n, fgpa);
return 0;
}
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 */
}
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.
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;
}
My assignment is to use two different kinds of loops (For, While, do While). The task is to ask the user to enter a number between 1 and 10 and then the program will count from 0 to the users number. Also, the program must be able to display an error message and ask the user to enter a number again if the user enters a number outside of 1 through 10. The part of the code with the error message and the prompt to enter a number again is working just fine. However, when I enter a number within the range, it either does nothing or counts from 0 to their number an infinite amount of times and won't stop looping the count. Please help!
#include <stdio.h>
int main(void)
{
//Variables
int num;
int zero;
//Explains to the user what the program will do
printf("This program will count from 0 to a number you pick.\n\n");
//Asks the user to input a value
printf("Please enter a number (between 1 and 10): \n");
scanf("%d", &num);
//If the correct range was selected by the user
while ( num >= 1 && num <= 10 )
{
for ( zero = 0; zero <= num; zero++ )
{
printf("%d...", zero);
}
}
//If a value outside of the accepted range is entered
while ( num < 1 || num > 10)
{
printf("I'm sorry, that is incorrect.\n");
printf("Please enter a number (between 1 and 10): \n");
scanf("%d", &num);
}
printf("\n\n\n");
return 0;
}
while ( num >= 1 && num <= 10 )
{
for ( zero = 0; zero <= num; zero++ )
{
printf("%d...", zero);
}
}
will run forever if num is between 1 and 10, since num is not changed inside the loop - once you're in, you're in for good.
If you enter a "bad" value then you'll skip this and go into your second while loop. However once you get out of that while loop by entering a "good" value, all that's left to execute is
printf("\n\n\n");
return 0;
You need to get rid of the first while loop and move the second one above the for loop:
#include <stdio.h>
int main(void)
{
//Variables
int num;
int zero;
//Explains to the user what the program will do
printf("This program will count from 0 to a number you pick.\n\n");
//Asks the user to input a value
printf("Please enter a number (between 1 and 10): \n");
scanf("%d", &num);
//If a value outside of the accepted range is entered
while ( num < 1 || num > 10)
{
printf("I'm sorry, that is incorrect.\n");
printf("Please enter a number (between 1 and 10): \n");
scanf("%d", &num);
}
for ( zero = 0; zero <= num; zero++ )
{
printf("%d...", zero);
}
printf("\n\n\n");
return 0;
}
Change two of your while loops to if guards,
num=1;
while(num>0)
{
//Asks the user to input a value
printf("Please enter a number (between 1 and 10): \n");
scanf("%d", &num);
//If the correct range was selected by the user
if ( num >= 1 && num <= 10 )
{
for ( zero = 0; zero <= num; zero++ )
{
printf("%d...", zero);
}
}
//If a value outside of the accepted range is entered
if ( num < 1 || num > 10)
{
printf("I'm sorry, that is incorrect.\n");
printf("Please enter a number (between 1 and 10): \n");
//scanf("%d", &num);
}
while(0); while(0); while(0); while(0); //gratuitous loops
do ; while(0); for(;0;);
}
Really Simple!
You may use a break inside the while loop:
#include <stdio.h>
int main(void)
{
//Variables
int num;
int zero;
//Explains to the user what the program will do
printf("This program will count from 0 to a number you pick.\n\n");
//Asks the user to input a value
printf("Please enter a number (between 1 and 10): \n");
scanf("%d", &num);
//If the correct range was selected by the user
while ( num >= 1 && num <= 10 )
{
for ( zero = 0; zero <= num; zero++ )
{
printf("%d...", zero);
}
break; // !!! Here !!!
}
//If a value outside of the accepted range is entered
while ( num < 1 || num > 10)
{
printf("I'm sorry, that is incorrect.\n");
printf("Please enter a number (between 1 and 10): \n");
scanf("%d", &num);
}
printf("\n\n\n");
return 0;
}