Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на C / C++ / Нейбауэр А. Моя первая программа на С.doc
Скачиваний:
182
Добавлен:
02.05.2014
Размер:
3.75 Mб
Скачать

Функция scanf()

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

Си++ работает со всеми функциями ввода языка Си, но имеет свое дополнительное средство ввода — стандартный поток ввода cin. Ввод в Си++ описан дальше в этой же главе.

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

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

___________________________

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

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

%d

целые числа

%u

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

%f

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

%e

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

%g

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

%c

символы

%s

строки

%o

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

%x

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

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

main()

{

float amount;

scanf("%f", &amount);

}

В этом примере функция 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().