vsscanf - преобразует данные в
vsscanf(3)
преобразует данные в
Other Alias
scanf, fscanf, sscanf, vscanf, vfscanf
ОБЗОР
#include <stdio.h>
int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);
#include <stdarg.h>
int vscanf(const char *format, va_list ap);
int vsscanf(const char *str, const char *format, va_list ap);
int vfscanf(FILE *stream, const char *format, va_list ap);
Требования макроса тестирования свойств для glibc
(см. feature_test_macros(7)):
vscanf(), vsscanf(), vfscanf():
_XOPEN_SOURCE >= 600 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L;
или
cc -std=c99
ОПИСАНИЕ
Группа функций
scanf() считывает вводимую информацию в соответствии с
форматом
format так, как описано ниже. В формате могут указываться
определители преобразования (conversion specifications); результаты
каждого преобразования, если они производились, сохраняются по адресам
параметров
указателей, передаваемых после
format. Каждый параметр
указатель должен быть того же типа, что и значение, получаемое в
результате преобразования данных в соответствии с форматом.
Если количество определителей преобразования в format превышает
количество параметров указателей, то результат не определён. Если
количество параметров указателей превышает количество определителей
преобразования, то лишние параметры указатели вычисляются, но
игнорируются.
Функция scanf() считывает информацию из стандартного потока ввода
stdin; fscanf() считывает информацию из потока, на который указывает
stream, а sscanf() считывает информацию из символьной строки, на
которую указывает str.
Функция vfscanf() является аналогом vfprintf(3) и читает информацию из
потока, на который указывает указатель stream, используя список
указателей переменной длины (смотрите stdarg(3)). Функция vscanf()
считывает список параметров переменной длины из стандартного ввода, а
функция vsscanf() считывает его из строки. Эти функции являются аналогами
функций vprintf(3) и vsprintf(3), соответственно.
Строка format состоит из последовательности инструкций (directives),
которые описывают порядок обработки входных символов. Если обработка
инструкции завершается с ошибкой, то чтение прекращается и scanf()
завершает работу. «Отказом» может быть: ошибка ввода, то есть
недоступность входных символов или ошибка совпадения, то есть получены
неподходящие данные (смотрите далее).
Инструкцией может быть:
-
Последовательность пробельных символов (пробел, табуляция, символ новой
строки и т. д.; смотрите isspace(3)). Эта инструкция совпадает с любым
количеством пустого места, включая отсутствие данных.
-
Обычный символ (т. е., отличный от пробельного или «%»). Такой символ должен
точно совпадать со следующим символом входных данных.
-
Определитель преобразования, который начинается с символа «%»
(процент). Последовательность символов ввода преобразуется в соответствии с
определителем, а результат помещается в соответствующий параметр
указатель. Если следующий элемент ввода не соответствует определителю
преобразования, то преобразование завершается с ошибкой — ошибкой
совпадения.
Каждый определитель преобразования в format начинается с символа «%»
или последовательности символов «%n$» (смотрите о разнице далее) за
которым следует:
-
Необязательный символ подавления назначения «*»: scanf() читает данные
как предписано определителем преобразования, но отбрасывает
их. Соответствующий параметр указатель необязателен, и этот определитель
не учитывается в счётчике успешных назначений, возвращаемом scanf().
-
Необязательный символ «m». Используется в строковых преобразованиях (%s,
%c, %[) и освобождает вызывающего от необходимости выделять
соответствующий буфер для хранения входных данных: вместо этого scanf()
выделяет буфер достаточного размера и присваивает адрес этого буфера
соответствующему параметру указателю, который должен быть указателем на
переменную char * (эту переменную не нужно инициализировать перед
вызовом). Вызывающий должен вызвать free(3) для этого буфера, как только
он станет ненужным.
-
Необязательное целое десятичное число, которое задаёт максимальную ширину
поля. Чтение символов прерывается по достижении этого максимума или при
нахождении несовпадающего символа, неважно что случится раньше. В
большинстве преобразований начальные пробельные символы отбрасываются
(исключения приведены далее), и эти отброшенные символы не учитываются в
максимальной ширине поля. В преобразованных строках ввода сохраняется
конечный байт null ('\0') для отметки конца ввода; в максимальной
ширине поля он также не учитывается.
-
Необязательный символ модификатора типа. Например, модификатор типа l
используется в преобразованиях целых чисел, например с помощью %d, для
указания того, что соответствующий параметр указатель ссылается на
long int, а не на int.
-
Определитель преобразования, который задаёт тип входного преобразования.
Определители преобразования в format бывают двух видов: начинающиеся с
«%» и начинающиеся с «%n$». Эти два вида не должны использоваться
одновременно в строке format, за исключением случая, когда строка,
содержащая определители «%n$», может включать %% и %*. Если в
format содержатся определители «%», то они задаются в порядке появления
параметров указателей, указанных после. В форме «%n$» (есть в
POSIX.1-2001, но отсутствует в C99), n — это десятичное целое, которое
задаёт в какое место должен быть помещён ввод, то есть указывает на
расположение n-го параметра указателя, передаваемого после format.
Преобразования
Следующие
символы модификаторов типа (type modifier characters) могут
появляться в определении преобразования:
h
Обозначает, что преобразование будет одним из d, i, o, u, x,
X или n и следующий указатель является указателем на short int или
на unsigned short int (но не int).
hh
Как h, но следующий указатель — указатель на signed char или
unsigned char.
j
Как h, но следующий указатель — указатель на intmax_t или
uintmax_t. Этот модификатор появился в C99.
l
Обозначает, что преобразование будет одним из d, i, o, u, x,
X или n и следующий указатель является указателем на long int или
unsigned long int (но не int), или что преобразование будет одним из
e, f или g и следующий указатель является указателем на double
(но не float). Указание двух символов l эквивалентно L. Если
используется с %c или %s, то соответствующий параметр считается
указателем на широкий символ или строку широких символов, соответственно.
L
Обозначает, что преобразование будет одним из e, f или g и
следующий указатель является указателем на long double или преобразование
будет одним из d, i, o, u или x и следующий указатель
является указателем на long long.
q
Эквивалентен L. Данный определитель отсутствует в ANSI C.
t
Как h, но следующий указатель — указатель на ptrdiff_t. Этот
модификатор появился в C99.
z
Как h, но следующий указатель — указатель на size_t. Этот модификатор
появился в C99.
Доступны следующие определители преобразования:
%
Совпадает с литерой «%». То есть %% в строке формата соответствует
одиночному символу данных «%». Преобразование не выполняется (но начальные
пробельные символы отбрасываются) и назначения не происходит.
d
Совпадает с необязательным знаковым десятичным целым; следующий указатель
должен быть указателем на int.
D
Эквивалентно ld; оставлено только для обратной совместимости (замечание:
есть только в libc4. В libc5 и glibc %D просто игнорируется, что приводит
к непонятным ошибкам в старых программах).
i
Совпадает с необязательным знаковым целым; следующий указатель должен быть
указателем на int. Целое считывается как шестнадцатеричное число, если
начинается с 0x или 0X, как восьмеричное, если начинается с 0 и как
десятичное в остальных случаях. Используются только символы, подходящие для
работы с выбранным основанием системы счисления.
o
Совпадает с необязательным беззнаковым восьмеричным целым; следующий
указатель должен быть указателем на unsigned int.
u
Совпадает с необязательным беззнаковым десятичным целым; следующий указатель
должен быть указателем на unsigned int.
x
Совпадает с необязательным беззнаковым шестнадцатеричным целым; следующий
указатель должен быть указателем на unsigned int.
X
Эквивалентно x.
f
Совпадает с необязательным знаковым числом с плавающей запятой; следующий
указатель должен быть указателем на float.
e
Эквивалентно f.
g
Эквивалентно f.
E
Эквивалентно f.
a
(C99) Эквивалентно f.
s
Совпадает с последовательностью непробельных символов; следующий указатель
должен указывать на первый элемент массива символов достаточной длины для
сохранения входной последовательности и завершающего байта null
('\0'), который добавляется автоматически. Входная строка обрывается
при появлении пробельного символа или достижении максимальной ширины поля,
неважно что случится раньше.
c
Совпадает с последовательностью символов, чья длина задаётся максимальной
шириной поля (по умолчанию 1); следующий указатель должен быть указателем
на char, и должно быть достаточно места для всех символов (завершающий
байт null не добавляется). Обычный пропуск начальных пробелов не
выполняется. Чтобы пропустить пробелы, явно укажите их в формате.
[
Совпадает с непустой последовательностью символов из задаваемого набора
допустимых символов; следующий указатель должен быть указателем на char и
должно быть достаточно места для всех символов в строке плюс завершающий
байт null. Обычный пропуск начальных пробелов не выполняется. Строка будет
состоять (или нет) из символов определённого набора; набор задаётся
указанием символов между символом открывающей скобки [ и закрывающей
скобки ]. Набором определяются исключающиеся символы, если первым
символом после открывающей скобки является символ диакритического знака
(^). Чтобы включить закрывающую скобку в набор, укажите её первым
символом после открывающей скобки или диакритического знака; в любой другой
позиции она закрывает набор. Символ переноса - также является
специализированным; если он указывается между двумя символами, то в набор
добавляются все лежащие в промежутке символы. Чтобы добавить в набор символ
переноса укажите его последним, перед конечной закрывающей
скобкой. Например, [^]0-9-] означает, что «все символы, кроме закрывающей
скобки, цифр от 0 до 9 и переноса». Строка обрывается при появлении символа
не из набора (или, при указании символа диакритического знака, из) или при
достижении ширины поля.
p
Совпадает со значением указателя (как выводится при %p в printf(3));
следующий указатель должен быть указателем на void.
n
Ничего не ожидается; вместо этого количество символов, использованных к
настоящему времени из ввода, сохраняется по следующему указателю, который
должен быть указателем на int. Это не преобразование и не
увеличивает счётчик, возвращаемый функцией. Назначение может подавляться при
указании символа подавления назначения *, но влияние этого на
возвращаемое значение не определено. Поэтому преобразования %*n лучше не
использовать.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении данные функции возвращают количество входных
совпавших и назначенных элементов, которое может быть меньше, чем
предусматривалось, или даже равно нулю, в случае преждевременной ошибки при
поиске совпадений.
Если конец входных данных был достигнут раньше, чем произошло хотя бы одно
совпадение или при ошибке совпадения возвращается значение EOF. Значение
EOF также возвращается при ошибке чтения; в этом случае для потока
устанавливается индикатор ошибки (смотрите ferror(3)), а в errno
указывается номер ошибки.
ОШИБКИ
EAGAIN
Файловый дескриптор stream помечен как неблокирующий, а чтение вызвало бы
блокировку.
EBADF
Неправильный файловый дескриптор для stream или он не открыт на чтение.
EILSEQ
Из входной байтовой последовательности невозможно создать корректный символ.
EINTR
Операция чтения была прервана сигналом; смотрите signal(7).
EINVAL
Недостаточно параметров или format равен NULL.
ENOMEM
Не хватает памяти.
ERANGE
Результат преобразования целого превысил бы размер, который можно хранить в
соответствующем целочисленном типе.
АТРИБУТЫ
Описание терминов данного раздела смотрите в
attributes(7).
Интерфейс Атрибут Значение
scanf(),
fscanf(),
sscanf(),
vscanf(),
vsscanf(),
vfscanf()
безвредность в потоках: безвредно (MT-Safe locale)
СООТВЕТСТВИЕ СТАНДАРТАМ
Функции
fscanf(),
scanf() и
sscanf() соответствуют C89, C99 и
POSIX.1-2001. В этих стандартах не определена ошибка
ERANGE.
Определитель q в 4.4BSD используется для long long, а определители
ll или L используются в GNU для преобразования целых чисел.
Версия Linux этих функций основана на библиотеке GNU libio. Более
точное описание функций можно найти в документации в формате info на
GNU libc (glibc-1.08).
ЗАМЕЧАНИЯ
Модификатор выделения-назначения «a»
Первоначально, в библиотеке GNU C поддерживалось динамическое выделение
памяти для входных строк при указании символа
a (нестандартное
расширение) (это свойство существует до glibc 2.0). То есть можно указать
scanf() выделить буфер под входную строку, передав в указателе только
указатель на буфер
*buf:
char *buf;
scanf("%as", &buf);
Использование буквы a для этой цели проблематично, так как a также
используется в стандарте ISO C как синоним f (ввод данных с плавающей
запятой). В POSIX.1-2008 для назначения с выделением определён модификатор
m (смотрите в
ОПИСАНИЕ выше).
Заметим, что модификатор a недоступен, если программа скомпилирована
посредством gcc -std=c99 или gcc -D_ISOC99_SOURCE (если не определён
_GNU_SOURCE); в этом случае a рассматривается как определитель чисел с
плавающей запятой (смотрите выше).
Поддержка модификатора m была добавлена в glibc начиная с версии 2.7, и в
новых программах нужно использовать этот модификатор вместо a.
Стандартизированный в POSIX модификатор m имеет дополнительные
преимущества над a:
Он может также применяться к определителям преобразования %c (например,
%3mc).
Исчезает неоднозначность с определителем преобразования чисел с плавающей
запятой %a (не подвержен влиянию gcc -std=c99).
ДЕФЕКТЫ
Все функции полностью соответствуют C89, но предоставляют дополнительные
определители q и a, а также дополнительные возможности определителей
L и l. Последнее может считаться дефектом, так как это изменяет
поведение определителей, заданное в C89.
Некоторые комбинации модификаторов типов и определителей преобразования,
определённые в ANSI C, не имеют смысла (например, %Ld). Хотя они могут
иметь хорошо описанное поведение в Linux, это не обязательно так на других
архитектурах. Поэтому, обычно, лучше использовать модификаторы, не
определённые в ANSI C, то есть использовать q вместо L в комбинации с
преобразованием d, i, o, u, x и X или ll.
Работа q отличается от работы в 4.4BSD, так как может использоваться при
преобразовании вещественных числе подобно L.
ПРИМЕР
Чтобы использовать определитель динамического выделения при преобразовании,
укажите m в качестве модификатора длины (в виде %ms или
%m[диапазон]). Вызывающий должен вызвать free(3) для
возвращённой строки как в следующем примере:
char *p;
int n;
errno = 0;
n = scanf("%m[a-z]", &p);
if (n == 1) {
printf("чтение: %s\n", p);
free(p);
} else if (errno != 0) {
perror("scanf");
} else {
fprintf(stderr, "Нет совпадающих символов\n");
}
Как показано в примере выше, необходимо вызывать free(3) только, если при
вызове scanf() была прочитана строка.