Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебник Моя первая программа на С++.docx
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
6 Мб
Скачать
☆

Функция scanf()

Функция scanf() является многоцелевой функцией, дающей возможность вводить в компьютер данные лю- бых типов. Название функции отражает ее назначение— функция сканирует (просматривает) клавиатуру, определяет, какие клавиши нажаты, и затем интерпретирует ввод, основываясь на указателях формата (SCAN Formatted characters). Так же, как и функция printf(), scanf() может иметь несколько аргументов, позволяя тем самым вводить значения числовых, символьных и строковых переменных в одно и то же время.

Так же, как список параметров printf(), список параметров функции scanf() состоит из двух частей: строки формата и списка данных (рис.5.7). Строка формата содержит указатели формата, здесь они носят назва- ние преобразователей символов*, которые определяют то, каким образом должны быть интерпретированы вводимые данные. Список данных содержит переменные, в которые должны быть занесены вводимые значения.

Рис. 5.7. Список параметров функции scanf() делится на две части

Указатели формата аналогичны тем, которые используются функцией printf():

%d целые числа

%u беззнаковые целые числа

%f вещественные числа, float

%e вещественные числа в экспоненциальной форме

%g вещественные числа в наиболее коротком из форматов %f или %e

%c символы

%s строки

%o целые числа в восьмеричной системе счисления

%x целые числа в шестнадцатеричной системе счисления

Вводя числовые или символьные данные, следует указывать в списке данных функции scanf() адрес пе- ременной, а не просто ее имя:

main()

{

float amount; scanf("%f", &amount);

}

* В оригинале conversion characters. (Прим.перев.)

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

На время работы функции scanf(), выполнение программы приостанавливается, и программа ожидает вво- да данных. Ввод заканчивается нажатием клавиши Enter.

Принцип работы с данными функции scanf() в корне отличается от работы функций gets() и getchar(). Для того чтобы понять, что именно происходит при вводе с помощью scanf(), необходимо детально рассмот- реть эти отличия.

Входной поток

Когда данные вводятся при помощи функции gets(), все символы, которые были набраны на клавиатуре до нажатия Enter, становятся значением переменной. Когда символ вводится с помощью функции getchar(), нажатие клавиши автоматически приводит к присвоению соответствующего символа перемен- ной.

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

Принято говорить, что scanf() получает данные из входного потока. Входным потоком называется после- довательность символов, поступающих из некоторого источника. В случае функции scanf() источником служит клавиатура. После нажатия клавиши Enter все данные, которые были введены к этому времени, передаются функции scanf() в виде пока еще бессмысленного набора символов, в том же порядке, в каком их набирали. Затем scanf() определяет, какие символы соответствуют типу, заданному указателем форма- та, а какие следует игнорировать. Указатели формата называют преобразователями символов, так как они берут исходные символы из входного потока и преобразуют их в данные, относящиеся к определенному типу. Рис.5.8 иллюстрирует этот процесс.

Функция scanf() игнорирует не содержащие информации знаки: пробелы, символы табуляции, символы новой строки, кроме тех случаев, когда текущий тип данных определен как char. Рассмотрим программу:

main()

{

int count; puts("Пожалуйста, введите число: "); scanf("%d", &count); printf("Число равно %d", count);

}

Рис. 5.8. Функция scanf() читает входной поток и определяет,какие данные следует ввести, а какие— иг- норировать

Перед тем как ввести число, вы можете нажимать на клавишу пробела столько, сколько хотите— Си будет игнорировать пробелы, в ожидании первого значимого символа. Затем Си попытается преобразовать сим- волы в соответствии с указателями формата в строке формата функции scanf(). Если эти символы соответ- ствуют формату (в данном случае— если это цифры), они будут внесены в переменную. Ввод данных пре- кратится, если встретится символ, формат которого не соответствует ожидаемому, то есть он не является цифрой. Например, если набрать на клавиатуре последовательность «123abc», то число 123 в нашем при- мере будет присвоено переменной count, а буквы «abc»— проигнорированы, как это показано на рис.5.9. Остановку ввода данных может вызвать пробел. Например, если напечатать «123», то переменной будет присвоено значение 12, а число 3— проигнорировано.

Рис. 5.9. Функция scanf() прекращает ввод данных,встретив первый не цифровой символ

Первый значимый символ должен соответствовать указанному в аргументе функции scanf() формату. Так, если напечатать последовательность «ABC123», программа проигнорирует ее всю целиком, и вы остане- тесь в неведении относительно значения переменной.

Какие символы программа расценивает как «подходящие», зависит от указателей формата. Если стоит указатель %d, то «подходящими» являются только цифры и знак «минус». Если поставить указатель %x, то соответствующими формату окажутся символы 0123456789ABCDE, так как все они используются при записи чисел в шестнадцатеричной системе счисления. Если же стоит указатель %c, принимаются любые символы, даже пробел внутри входного потока функция scanf() в этом случае не игнорирует. Если напи- сать инструкцию:

char letter; scanf("%c", &letter);

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

Вводя строку, функция scanf() начнет присваивание значения с первого значимого символа, игнорируя пробелы впереди, и остановит присваивание, встретив первый пробел среди значимых символов. Взгля- ните на программу:

main()

{

char name[25];

puts("Пожалуйста, введите Ваше имя: "); scanf("%s", name);

puts(name);

}

Обратите внимание, оператор получения адреса не используется с именем строковой переменной. Если вы наберете на клавиатуре «Нэнси» и нажмете Enter, эти символы будут присвоены переменной name. Даже если набрать «Нэнси Чезин», scanf() начнет присвоение символов с первого значимого символа и остановит, встретив первый пробел, так что значением переменной все равно станет только имя Нэнси, а остальное программа проигнорирует (рис.5.10).

Рис. 5.10. Функция scanf() прекращает чтение символов в строкепри появлении первого пробела

Из-за этой особенности функции scanf(), она является не слишком удобной для ввода строк. В этих случа- ях лучше использовать функцию gets().