Intereting Posts
Как конкатенировать строки с препроцессором C с точками в них? Определите, какой день недели начинается с Как связать реализацию glibc iconv? Есть ли способ найти номер строки текущей строки, считанной из файла? Отдел безопасных плавающих точек Программно проверить сертификат X509 и совпадение с закрытым ключом Определите, является ли строка допустимым адресом IPv4 в C передача целочисленных аргументов при использовании execve Как установить языковой стандарт (-std) для статического анализатора Clang в Qt Creator Встраивание CPython: как вы создаете контенты Python для переноса указателей обратного вызова C? Как работает реализация glibc strlen () Как остановить пользователя, вводя char в качестве int-входа в C Сходства и различия между массивами и указателями на практическом примере C расширение макропроцессора до процессора Как разрешить ошибку «параметр имеет неполный тип»?

Вводят float в программу, которая имеет дело только с ints

У меня есть программа, но когда я вводят числа с плавающей запятой всякий раз, когда программа запрашивает входные данные, программа внезапно пропускает шаг и перемещается на конечный вывод. Программа ниже:

#include  #include  int main() { int a,b,c; int i; printf("Please enter a number: "); scanf("%d", &a); printf("Please enter a number: "); scanf("%d", &b); c = 0; for(i=0; i < b; i++) { c = c + a; } printf("%dx %d = %d\n", a, b, c); return 0; } 

Когда я ввожу int для a и float для b , программа выведет продукт как ожидалось, если числа после десятичной точки для b будут усечены. Однако, когда я вводил float для a , программа не принимает значение для второго номера b и вместо этого пропускает этот шаг и выводит целочисленную версию ax -858993460 = 0 .

Например:

a = int, b = float

Введите число: 3
Введите число: 5.6
3 x 5 = 15

a = float, b = пропущено

Введите число 3.9
Введите число: 3 x -858993460 = 0

Все недостатки в коде преднамеренно, но я просто хотел знать, почему он ведет себя так, как я объяснял выше. Я знаю, что это связано с попыткой ввода float в целое число со знаком, но я не уверен, что именно заставляет его пропускать второй scanf("%d", &b) . Может ли кто-нибудь объяснить, почему это происходит?

Благодарю.

Похоже, scanf() читает ваш «3» во втором случае и игнорирует «9».

Затем, когда вызывается второй scanf() , во входном буфере уже есть текст («.9»).

Я не могу точно сказать, что он делает с «.9». Он, возможно, нашел точку и просто прервался там, а b неинициализирован. Необходимо просто определить, что происходит, пройдя через отладчик.

Но, в основном, не все входные данные обрабатываются первым вызовом scanf() и поэтому второй вызов пытается прочитать. И поэтому он не ждет, чтобы вы ввели какие-либо данные для второго вызова.

Вход в консоль буферизируется по строке ; при вводе 3.9 в спецификатор формата %d потребляется только 3, остальные данные остаются буферизированными, поэтому второй вызов scanf () пытается преобразовать его в соответствии со своим спецификатором, он находит '.' и прерывает преобразование, оставляя b неопределенным.

scanf() будет продолжать «просачиваться» до тех пор, пока не будет уничтожен '\n' в конце входных данных. Вы можете сделать это так:

  printf("Please enter a number: "); scanf("%d", &a); while( getchar() != '\n' ) { /* do nothing */ } printf("Please enter a number: "); scanf("%d", &b); while( getchar() != '\n' ) { /* do nothing */ } 

Обратите внимание, что если спецификатор формата %c , требуется модификация кода «флеш», потому что преобразованный символ может уже быть '\n' :

 scanf("%c", &c); while( c != '\n' && getchar() != '\n' ) { /* do nothing */ } 

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

И этот конкретный символ рассматривается как непрочитанный и используется как первый символ следующего поля ввода или любой последующей операции чтения.

В приведенном выше примере он сканирует 3 а затем не может разрешить . в спецификатор формата "%d" . Следовательно, он сохраняет 3 в переменной, оставляя .9 как непрочитанный. Элемент управления, когда он переходит к следующему оператору scanf , проверяет . , но опять же, поскольку он не может решить . для форматирования спецификатора "%d" , он пропускает входное сканирование для этого поля.

Теперь, когда переменная b не была назначена, она содержит некоторое количество мусора . И любая арифметическая операция со значениями мусора приводит к значениям мусора.