2010-08-28 2 views
2

Я получаю странную проблему при использовании scanf() для хранения данных в объединении.Ошибка при использовании 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); 

} 

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

[email protected]:~/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 перед форматированием строки. [ЗсапЕ ("\ п% с", & ч);]

#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); 

    } 
+1

Что вы подразумеваете под точный выход? вы можете немного объяснить. – mhshams

+0

@mohammad shams Точный выход = правильный вывод – Searock

+0

Что случилось с моим вопросом? Почему меня проголосовали? – Searock

ответ

2

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

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

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

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

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

+0

Спасибо за красивое объяснение. Большое спасибо :) – Searock

2

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

+0

Я удалил/n из программы, но все равно дает мне ту же ошибку. Я прошу вас скопировать код кода и попробовать запустить его. Я не знаю, что происходит. – Searock

1

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

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

+0

Извините, но я не могу понять, что вы пытаетесь сказать. – Searock

Смежные вопросы