Reputation: 33
I can't really explain it except that scanf()
is only reading the first value, and then the calculations are made based off of that.
int main() {
int i, students = 0;
char name[20];
int tests;
float test_score;
int test_sum = 0;
char letter_grade;
double test_average;
printf("Number of students: ");
scanf("%d", &students);
for (i = 0; i < students; i++) {
printf("\nStudent name %d: ", i + 1);
scanf(" %s", &name);
fflush(stdin);
printf("Number of test(s) for %s: ", name);
scanf("%d", &tests);
fflush(stdin);
printf("Enter %d test score(s) for %s: ", tests, name);
if (i < students) {
scanf("%f", &test_score);
test_sum += test_score;
test_average = test_sum / (float)tests;
}
printf("Average test score: %.2f", test_average);
fflush(stdin);
}
return 0;
}
Say I enter 2 students, the first student with 2 test scores, then enter 45 87. I should be getting 66.00, but I'm getting 22.50. For the second student, I'd enter 3 test scores of 100 55 87, and I get 48.33. Waaayyy off.
I know I'm doing something wrong, but I can't figure out, because I had it working before, but the loop wouldn't continue to the second student.
Upvotes: 3
Views: 1766
Reputation: 16540
the posted code contains several problems including
int
and float
and double
variablesscanf()
scanf()
fflush(stdin)
is specifically listed as undefined behaviour in the C standardThe following proposed code fixes all the above problems and compiles cleanly
#include <stdio.h>
#include <stdlib.h> // exit(), EXIT_FAILURE
// prototypes
void flushStdin( void );
int main( void )
{
int numStudents = 0;
char studentName[20];
int numTests;
double test_score;
double test_sum = 0.0;
//char letter_grade;
double test_average;
printf("Number of students: ");
if( 1 != scanf("%d", &numStudents) )
{ // then scanf failed
perror( "scanf for number of students failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
flushStdin();
for (int i = 0; i < numStudents; i++)
{
printf("\nStudent name %d: ", i + 1);
if( 1 != scanf(" %s", studentName) )
{ // then scanf failed
perror( "scanf for student name failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
flushStdin();
printf("Number of test(s) for %s: ", studentName);
if( 1 != scanf("%d", &numTests) )
{ // scanf failed
perror( "scanf for number of tests failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
test_sum = 0.0;
printf("Enter %d test score(s) for %s: ", numTests, studentName);
for( int j=0; j<numTests; j++ )
{
if( 1 != scanf("%lf", &test_score) )
{ // then scanf failed
perror( "scanf for test score failed");
exit( EXIT_FAILURE );
}
// implied else, scanf successful
flushStdin();
test_sum += test_score;
}
test_average = test_sum / numTests;
printf("Average test score: %.2lf", test_average);
}
return 0;
} // end function: main
void flushStdin()
{
int ch;
while( (ch = getchar() ) != EOF && '\n' != ch);
}
Upvotes: 1
Reputation: 164
if (i < students) {
scanf("%f", &test_score);
test_sum += test_score;
test_average = test_sum / (float)tests;
}
Should be :
test_sum = 0;
for (int j = 0; j < tests; j++) {
scanf("%f", &test_score);
test_sum += test_score;
}
test_average = test_sum / (float)tests;
Upvotes: 1
Reputation: 249153
You always need to check the return value of scanf()
to see how many tokens it read. If it fails to read, you need to take corrective action.
It's not clear why you'd need fflush(stdin)
every time.
Upvotes: 1