scanf () только чтение первого ввода (число)
Я действительно не могу объяснить это, за исключением того, что scanf() только читает первое значение, а затем вычисления производятся на основе этого.
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;
}
Скажем, я ввожу 2 студента, первый студент с 2 баллами теста, затем введите 45 87. Я должен был получить 66.00, но я получаю 22.50. Для второго студента я бы ввел 3 тестовых балла из 100 55 87, и я получаю 48,33. Waaayyy выкл.
Я знаю, что делаю что-то не так, но я не могу понять, потому что у меня это работало раньше, но цикл не стал бы продолжать со вторым учеником.
3 ответа:
if (i < students) { scanf("%f", &test_score); test_sum += test_score; test_average = test_sum / (float)tests; }Должно быть:
test_sum = 0; for (int j = 0; j < tests; j++) { scanf("%f", &test_score); test_sum += test_score; } test_average = test_sum / (float)tests;
Вам всегда нужно проверить возвращаемое значение
scanf(), чтобы увидеть, сколько маркеров оно считывает. Если он не читается, вам нужно принять корректирующие меры.Непонятно, зачем вам нужно
fflush(stdin)каждый раз.
Опубликованный код содержит несколько проблем, включая
- можно ввести только один тестовый балл
- случайное сочетание
intиfloatиdoubleпеременных- неверный формат строк для вызовов
scanf()- число неиспользуемых переменных
- неспособность проверить наличие ошибок при вызовах
scanf()- плохое именование переменных. Имена переменных должны указывать на содержание или использование (или лучше и то, и другое)
- вызов
fflush(stdin)конкретно указан как неопределенное поведение в стандарте С- test_sum не инициализируется повторно между учащимися
Следующий предлагаемый код исправляет все вышеперечисленные проблемы и компилирует чисто
#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); }