Ошибка использования scanf () для пользовательского ввода - PullRequest
2 голосов
/ 28 августа 2010

У меня странная проблема при использовании scanf() для хранения данных в объединении.

Вот мой код

#include <stdio.h>

union Student
{
    float score;
    char grade;
};

int main(void)
{
    union Student jack;

    printf("Enter student score : ");
    scanf("%f", &jack.score);
    printf("Score : %f", jack.score);

    jack.score=0;

    printf("Enter student grade : ");
    scanf("%c", &jack.grade);
    printf("Grade : %c", jack.grade);

}

Я получаю следующий вывод

searock@searock-desktop:~/Desktop$ ./union
Enter student score : 12
Score : 12.000000Enter student grade : Grade :

но если я изменю свой код на:

#include <stdio.h>

union Student
{
    float score;
    char grade;
};

int main(void)
{
    union Student jack;

    printf("Enter student grade : ");
    scanf("%c", &jack.grade);
    printf("Grade : %c\n", jack.grade);

    printf("Enter student score : ");
    scanf("%f", &jack.score);
    printf("Score : %f\n", jack.score);

}

Это даст мне точный вывод [правильный вывод].Я знаю, что это не хороший пример, но кто-то может объяснить мне, что происходит?

Модифицированный код: Добавьте \ n перед строкой форматирования.[scanf ("\ n% c", & ch);]

#include <stdio.h>

    union Student
    {
        float score;
        char grade;
    };

    int main(void)
    {
        union Student jack;

        printf("Enter student score : ");
        scanf("%f", &jack.score);
        printf("Score : %f", jack.score);

        jack.score=0;

        printf("Enter student grade : ");
        scanf("\n%c", &jack.grade);
        printf("Grade : %c", jack.grade);

    }

Ответы [ 3 ]

2 голосов
/ 28 августа 2010

В первом примере первый scanf() читает число до, но не включая символ новой строки (при условии, что вы не вводите только пробелы и символы новой строки; если вы это сделаете, он продолжит ждать ввода, пока вы не введете число или не число - где пробелы и т. д. не считаются ни числом, ни числом). Затем вторая scanf() со спецификатором формата '%c' не пропускает пробел (в отличие от большинства других спецификаторов формата) и читает новую строку (при условии, что вы ввели новую строку сразу после конца числа; если вы ввели что-то еще) - пробел или буква, возможно, он читает этот символ), полностью игнорируя все, что вы ввели во второй строке. (Действительно, когда я запускаю код, мне не нужно ничего вводить для второй партии ввода. Попробуйте ввести «3.14 + C» или «3.14C» и символ новой строки.)

Во втором примере первый scanf() читает первый символ. Вторая scanf() пропускает пробел, включая символы новой строки, пока не найдет число или что-то, что определенно не является числом (например, буквой).

Это прекрасная демонстрация того, почему большинство людей избегают scanf(); очень трудно обеспечить удовлетворительный контроль над ним. Вам было бы лучше прочитать строки (возможно, используя fgets(); определенно не использовать gets()), а затем проанализировать их с помощью sscanf(). Тогда вы получите нормальное поведение для обоих примеров.

Обратите внимание, что ваша проблема совершенно не связана с использованием union; ваш код в порядке, что работает. Ваша проблема связана с использованием scanf().

Незначительная рекомендация: при печати строк вывода - кроме подсказок - добавьте новую строку в конце строки формата.

2 голосов
/ 28 августа 2010

Разница из-за \n в строке. Это предотвращает кэширование строки в буфере вывода и вместо этого сразу отображается на экране.

1 голос
/ 28 августа 2010

В первом примере вы читаете число с плавающей точкой, а затем следующий символ, который будет новой строкой, следующей за плавающей точкой (вы нажали клавишу Enter после ввода числа с плавающей запятой).

Во втором примере *Спецификаторы формата 1003 * включают эту новую строку, поэтому первая scanf() читает символ, за которым следует новая строка, а вторая scanf() читает плавающее число, за которым следует новая строка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...