#c #string #math #integer #scanf
#c #строка #математика #целое число #scanf
Вопрос:
Я, по сути, решил свою проблему, объединив работу, но я просто хочу понять, почему такое поведение происходит, поэтому сначала мой код:
#include <stdio.h>
#pragma warning(disable : 4996) // Just so MVS stops having a meltdown over scanf.
/* Simple question and answer of math equasion. */
int main()
{
printf("What is 5 5?nnAnswer: ");
int userInput;
if (scanf("%i", amp;userInput) amp;amp; userInput != (5 5)) // Give 'userInput' a variable from scanf and compare to hard coded answer.
{
printf("nIncorrect!n");
return 0;
}
printf("nCorrect!n"); // Else without the 'else'.
return 1;
}
Это достаточно простой, жестко закодированный математический вопрос и запрос ответа от пользователя. Предполагаемый ответ будет правильным для соответствия решаемого ответа userInput
, и все, что не совпадает, считается неправильным. Когда я передаю ему кучу букв или просто просто «asdf», он рассматривает его как правильное и выдает отрицательное число: -858993460.
Моя работа заключается в добавлении || userInput < 0
к моему оператору if следующим образом:
if (scanf("%i", amp;userInput) amp;amp; userInput != (5 5) || userInput < 0)
Итак, по сути, проблема была решена с помощью какой-то гибкой ленты, нанесенной на нее, но, похоже, я не могу ответить на вопрос: «Почему он выдает это отрицательное число, независимо от того, какие буквы или нечисловые символы я ему добавляю?»
Мои извинения, если на это уже был дан ответ. Я пытался искать по любым ключевым словам, которые я мог придумать, но безрезультатно.
Комментарии:
1. Что вы подразумеваете под «выдает отрицательное число»? В показанном коде нет ничего, что печатало бы число. В любом случае, основная проблема заключается в том, что код не совсем корректен. Если введен неверный ввод,
scanf
вернетсяEOF
. В этом случае ваш исходный код по-прежнему рассматривает его как правильный регистр. Проверка должна бытьscanf() == 1
.2. Если я добавлю
printf("i%", userInput);
ниже правильное при вводе букв, вот где это дает мне указанное отрицательное число. Извините, я должен был добавить это в код.3. Ну, это потому
scanf
, что сбой и не устанавливает никакого значенияuserInput
. ПосколькуuserInput
он не инициализирован, в этом случае он будет просто содержать данные мусора. Вы не должны использоватьuserInput
, еслиscanf
не завершится успешно.4. Нет, в случае
scanf
сбоя он вообще не трогаетсяuserInput
. Это просто любой случайный мусор, который оказывается в переменной. Обращение к переменным, которые не инициализированы, является неопределенным поведением, и поэтому значение непредсказуемо и не имеет значения.5. Кроме того, вы почти наверняка никогда не захотите использовать
scanf
with%i
и, возможно, должны использовать%d
вместо этого.%i
будет принимать восьмеричные числа, поэтому, если вы введете 012, это тоже правильно , поскольку 012 декабря равно 010 декабря.
Ответ №1:
scanf
Функция возвращает количество совпадающих элементов, поэтому в логическом содержимом она принимает значение true, если вы ввели число, и false, если вы этого не сделали. Это также означает, что значение не записывается userInput
, поэтому его значение (поскольку оно не было инициализировано) все еще не определено.
Это означает, что в вашем условии указано, что ответ «Неверный», если пользователь ввел число, а оно не равно 10, поэтому оно считается правильным, если вы не ввели число. Вместо этого вы хотите напечатать «Неверно», если либо число не введено, либо введенное число не равно 10:
if (!scanf("%i", amp;userInput) || userInput != (5 5))
Комментарии:
1. Интересно. Спасибо за ответ. Я все еще привыкаю к логическим соглашениям. Мои первоначальные мысли с дополнительными инструкциями заставляют меня думать, что лучший маршрут сейчас с моим фрагментом кода — поменять местами условия. Вместо того, чтобы делать оператор if для чего-то неправильного, я, вероятно, должен выбрать оператор if для правильного ответа, и если он не совпадает
(5 5)
, он просто передаст его в другой раздел. Насколько я понимаю сейчас,userInput
это просто приводит к случайным ненужным данным, поэтому при печати он выдает мне указанный результат, если встречается с буквами?2. @BluZero Вы хотите сначала проверить, был ли
scanf
он успешным или нет (что делает этот код), а затем читать толькоuserInput
в том случае, если он был.3. Если конец ввода достигнут до первого допустимого преобразования или ошибки сопоставления,
EOF
возвращается (обычно-1
), который также будет проверять true с помощьюscanf("%i", amp;userInput)