Урок 6.3. Форматный ввод

6.3. Форматный ввод

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

scanf(<управляющая строка>,<список ввода>);

где <управляющая строка> является строкой Си, символами которой могут быть:

а) пробелы, символы табуляции и новой строки ("пустые" символы). Если они есть, то они игнорируются;

б) обычные символы (кроме %). Если они есть, то они должны совпадать с очередными символами во входном потоке данных;

в) форматы, начинающиеся с символа %, за которым может быть записан символ запрещения присваивания * , может быть число, задающее ширину поля входного данного, и обязательно должен быть символ преобразования. * <список ввода> состоит, как и для функции printf(), из элементов, отделенных друг от друга запятой.

Однако в качестве элемента ввода указывается адрес переменной, куда должно поступить значение, а не имя переменной. Чтобы получить адрес, нужно к переменной применить операцию взятия адреса & . Например, если name имя переменной, то ее адрес будет &name.

Для массивов имя массива является его адресом. Форматы в управляющей строке аналогичны форматам в строке вывода функции printf(), но имеются некоторые отличия. Формат ввода имеет следующую общую форму записи:

%*<ширина_l_символ_преобразования>

В форматах управляющей строки используются следующие наиболее часто употребляющиеся символы преобразования:

Таблица. Спецификации формата функции scanf()

Код

Назначение

%a,%A читает значение с плавающей точкой (только C99)
%c на входе ожидается одиночный символ
%d на входе ожидается десятичное целое
%i читает целое в любом формате (десятичное, восьмеричное или шестнадцатеричное)
%e,%E на входе ожидается число с плавающей точкой в форме с точкой или с порядком
%f читает число с плавающей точкой
%F Аналогично коду %f (только С99)
%g,%G читает число с плавающей точкой
%o читает восьмеричное число
%s на входе ожидается строка символов. Соответствующий элемент ввода должен быть адресом массива, способного вместить всю строку, включая нуль-символ \0, который добавляет сама функция;
%x,%X читает шестнадцатеричное число
%p читает указатель
%n принимает целое значение, равное количеству прочитанных до сих пор символов, см. пример с printf() в предыдущей главе
%u читает десятичное целое без знака
%[ ],%[^] просматривает набор символов на допустимость/недопустимость
%% читает знак процента

Перед символами преобразования u, x, o и d может стоять буква l, указывающая на то, что соответствующий элемент списка ввода является адресом данного целого типа, описанного с модификатором long. Если буква l стоит перед символом преобразования f или e, то соответствующий элемент списка ввода является адресом данного, описанного как long float или long double соответственно.

Если в формате записана <ширина> , то она определяет максимальный размер поля данного. Меньшее число позиций может быть прочитано, если во входном потоке встретится разделитель полей или символ, который нельзя преобразовать в соответствии с указанным форматом.

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

Первое поле данного во входной строке преобразуется в соответствии с первым форматом, и полученное значение заносится по адресу первого элемента списка ввода. Следующее поле переводится в соответствии со вторым форматом и т.д.

Поле данного во входной строке определяется как группа символов до (но не включая) символа-разделителя. Символами-разделителями могут быть пробелы, символы табуляции и символы перехода на новую строку; группа символов до такого символа, который не может быть преобразован в соответствии с текущим форматом; группа из n символов, где n – значение ширины поля. Например, обращение:

int r;
float x;
 
char city[50];
scanf("%d %f %s", &r,&x,city);
//с входной строкой
25 54.32e-1 Кишинев

присвоит значение 25 переменной r, значение 5.432 переменной x и строку "Кишинев" с добавлением в конце нуль-символа \0 пошлет в массив city. Обратите внимание на то, что для city не указана операция взятия адреса &, так как в Си значением имени массива является адресная константа, определяющая начальный адрес памяти, с которого располагаются элементы массива. Видоизмененное обращение:

scanf("r=%d x=%f city=%s", &r,&x,city);

с непустыми символами в управляющей строке требует входной строки с точно такими же непустыми символами:

r=25 x=54.32e-1 city=Кишинев

Обращение с указанием в форматах ширины поля данного и с применением символа запрещения присваивания:

scanf("%25d %f %*d %2s",&r,&x,city);

для которого подготовлена, например, входная строка

56789 0123 45a72 ,

присвоит переменной r значение 56, переменной x значение 789.0, пропустит данное 0123, так как в формате стоит символ запрещения присваивания, и поместит строку "45" в city. Последующее обращение к вводу приведет к чтению из буфера, начиная с позиции буквы a. Если бы были прочтены все данные из входного буфера, то даже в этом случае в буфере остается признак конца ввода, так как он является разделителем полей.

Этот факт необходимо учитывать в прикладных программах, которые неоднократно запрашивают исходные данные. Для того, чтобы повторный ввод отработал корректно, после функции scanf() рекомендуется записать getchar(), которая "скушает" признак конца ввода.

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

Пример использования "шаблонов", формат [ ], [^ ].
Формат [ ] позволяет получить строку, содержащую любые символы, указанные в квадратных скобках. Как только на ввод поступает символ, не входящий в указанный набор, считывание данных прекращается. Формат [^ ], наоборот, помещает в строку символы, не входящие в указанный набор, до тех пор пока не встретит любой из указанных.

char str[30]="";
 
// строке str будет присвоена последовательность символов из цифр,
// как только встретится не цифра ввод, будет прекращен
scanf("%[0-9]", str);
 
// строке будет присвоена последовательность символов
// до любого из указанных знаков препинания, если на клавиатуре
// набрать Hello, World! , то str будет присвоено Hello
scanf("%[^;:,!?]", str);
 
// можно ввести любые символы, до тех пор, пока не будет
// введена b или m
scanf("%[^b,^m]", str);

 

 

рассказать друзьям и получить подарок

Оставить комментарий

Ваш email не будет опубликован. Обязательные поля отмечены *

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Translate Переводчик

Подписка на новости

SmartResponder.ru
Ваш e-mail: *
Ваше имя: *

Хостинг для Wordpress сайтов