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 3

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) каждый раз.

Опубликованный код содержит несколько проблем, включая

  1. можно ввести только один тестовый балл
  2. случайное сочетание int и float и double переменных
  3. неверный формат строк для вызовов scanf()
  4. число неиспользуемых переменных
  5. неспособность проверить наличие ошибок при вызовах scanf()
  6. плохое именование переменных. Имена переменных должны указывать на содержание или использование (или лучше и то, и другое)
  7. вызов fflush(stdin) конкретно указан как неопределенное поведение в стандарте С
  8. 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);
}