Scroll to navigation

SCANF(3) Руководство программиста Linux SCANF(3)

ИМЯ

scanf, fscanf, sscanf, vscanf, vsscanf, 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():

_ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L

ОПИСАНИЕ

Группа функций 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().
Для десятичных преобразований необязательный символ кавычки ('). Указывает, что входное число можно содержать разделитель тысяч, определяемый категорией LC_NUMERIC текущей локали (смотрите setlocale(3).) Символ кавычки может быть до или после символа подавления '*'.
Необязательный символ «m». Используется в строковых преобразованиях (%s, %c, %[) и освобождает вызывающего от необходимости выделять соответствующий буфер для хранения входных данных: вместо этого scanf() выделяет буфер достаточного размера и присваивает адрес этого буфера соответствующему параметру указателю, который должен быть указателем на переменную char * (эту переменную не нужно инициализировать перед вызовом). Вызывающий должен вызвать free(3) для этого буфера, как только он станет ненужным.
Необязательное целое десятичное число, которое задаёт максимальную ширину поля. Чтение символов прерывается по достижении этого максимума или при нахождении несовпадающего символа, неважно что случится раньше. В большинстве преобразований начальные пробельные символы отбрасываются (исключения приведены далее), и эти отброшенные символы не учитываются в максимальной ширине поля. В преобразованных строках ввода сохраняется конечный байт null ('\0') для отметки конца ввода; в максимальной ширине поля он также не учитывается.
An optional type modifier character. For example, the l type modifier is used with integer conversions such as %d to specify that the corresponding pointer argument refers to a long rather than a pointer to an int.
Определитель преобразования, который задаёт тип входного преобразования.

Определители преобразования в format бывают двух видов: начинающиеся с «%» и начинающиеся с «%n$». Эти два вида не должны использоваться одновременно в строке format, за исключением случая, когда строка, содержащая определители «%n$», может включать %% и %*. Если в format содержатся определители «%», то они задаются в порядке появления параметров указателей, указанных после. В форме «%n$» (есть в POSIX.1-2001, но отсутствует в C99), n — это десятичное целое, которое задаёт в какое место должен быть помещён ввод, то есть указывает на расположение n-го параметра указателя, передаваемого после format.

Преобразования

Следующие символы модификаторов типа (type modifier characters) могут появляться в определении преобразования:

Indicates that the conversion will be one of d, i, o, u, x, X, or n and the next pointer is a pointer to a short or unsigned short (rather than int).
Как h, но следующий указатель — указатель на signed char или unsigned char.
Как h, но следующий указатель — указатель на intmax_t или uintmax_t. Этот модификатор появился в C99.
Indicates either that the conversion will be one of d, i, o, u, x, X, or n and the next pointer is a pointer to a long or unsigned long (rather than int), or that the conversion will be one of e, f, or g and the next pointer is a pointer to double (rather than float). Specifying two l characters is equivalent to L. If used with %c or %s, the corresponding parameter is considered as a pointer to a wide character or wide-character string respectively.
Обозначает, что преобразование будет одним из e, f или g и следующий указатель является указателем на long double или преобразование будет одним из d, i, o, u или x и следующий указатель является указателем на long long.
Эквивалентен L. Данный определитель отсутствует в ANSI C.
Как h, но следующий указатель — указатель на ptrdiff_t. Этот модификатор появился в C99.
Как h, но следующий указатель — указатель на size_t. Этот модификатор появился в C99.

Доступны следующие определители преобразования:

%
Совпадает с литерой «%». То есть %% в строке формата соответствует одиночному символу данных «%». Преобразование не выполняется (но начальные пробельные символы отбрасываются) и назначения не происходит.
Совпадает с необязательным знаковым десятичным целым; следующий указатель должен быть указателем на int.
Совпадает с необязательным знаковым целым; следующий указатель должен быть указателем на int. Целое считывается как шестнадцатеричное число, если начинается с 0x или 0X, как восьмеричное, если начинается с 0 и как десятичное в остальных случаях. Используются только символы, подходящие для работы с выбранным основанием системы счисления.
Совпадает с необязательным беззнаковым восьмеричным целым; следующий указатель должен быть указателем на unsigned int.
Совпадает с необязательным беззнаковым десятичным целым; следующий указатель должен быть указателем на unsigned int.
Matches an unsigned hexadecimal integer (that may optionally begin with a prefix of 0x or 0X, which is discarded); the next pointer must be a pointer to unsigned int.
Эквивалентно x.
Совпадает с необязательным знаковым числом с плавающей запятой; следующий указатель должен быть указателем на float.
Эквивалентно f.
Эквивалентно f.
Эквивалентно f.
(C99) Эквивалентно f.
Совпадает с последовательностью непробельных символов; следующий указатель должен указывать на первый элемент массива символов достаточной длины для сохранения входной последовательности и завершающего байта null ('\0'), который добавляется автоматически. Входная строка обрывается при появлении пробельного символа или достижении максимальной ширины поля, неважно что случится раньше.
Совпадает с последовательностью символов, чья длина задаётся максимальной шириной поля (по умолчанию 1); следующий указатель должен быть указателем на char, и должно быть достаточно места для всех символов (завершающий байт null не добавляется). Обычный пропуск начальных пробелов не выполняется. Чтобы пропустить пробелы, явно укажите их в формате.
[
Matches a nonempty sequence of characters from the specified set of accepted characters; the next pointer must be a pointer to char, and there must be enough room for all the characters in the string, plus a terminating null byte. The usual skip of leading white space is suppressed. The string is to be made up of characters in (or not in) a particular set; the set is defined by the characters between the open bracket [ character and a close bracket ] character. The set excludes those characters if the first character after the open bracket is a circumflex (^). To include a close bracket in the set, make it the first character after the open bracket or the circumflex; any other position will end the set. The hyphen character - is also special; when placed between two other characters, it adds all intervening characters to the set. To include a hyphen, make it the last character before the final close bracket. For instance, [^]0-9-] means the set "everything except close bracket, zero through nine, and hyphen". The string ends with the appearance of a character not in the (or, with a circumflex, in) set or when the field width runs out.
Matches a pointer value (as printed by %p in printf(3)); the next pointer must be a pointer to a pointer to void.
Ничего не ожидается; вместо этого количество символов, использованных к настоящему времени из ввода, сохраняется по следующему указателю, который должен быть указателем на int. Это не преобразование и не увеличивает счётчик, возвращаемый функцией. Назначение может подавляться при указании символа подавления назначения *, но влияние этого на возвращаемое значение не определено. Поэтому преобразования %*n лучше не использовать.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

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

Если конец входных данных был достигнут раньше, чем произошло хотя бы одно совпадение или при ошибке совпадения возвращается значение EOF. Значение EOF также возвращается при ошибке чтения; в этом случае для потока устанавливается индикатор ошибки (смотрите ferror(3)), а в errno указывается номер ошибки.

ОШИБКИ

Файловый дескриптор stream помечен как неблокирующий, а чтение вызвало бы блокировку.
Неправильный файловый дескриптор для stream или он не открыт на чтение.
Из входной байтовой последовательности невозможно создать корректный символ.
Операция чтения была прервана сигналом; смотрите signal(7).
Недостаточно параметров или format равен NULL.
Не хватает памяти.
Результат преобразования целого превысил бы размер, который можно хранить в соответствующем целочисленном типе.

АТРИБУТЫ

Описание терминов данного раздела смотрите в 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() была прочитана строка.

СМ. ТАКЖЕ

getc(3), printf(3), setlocale(3), strtod(3), strtol(3), strtoul(3)

ЗАМЕЧАНИЯ

Эта страница является частью проекта Linux man-pages версии 5.10. Описание проекта, информацию об ошибках и последнюю версию этой страницы можно найти по адресу https://www.kernel.org/doc/man-pages/.

ПЕРЕВОД

Русский перевод этой страницы руководства был сделан Alexander Golubev <fatzer2@gmail.com>, Azamat Hackimov <azamat.hackimov@gmail.com>, Hotellook, Nikita <zxcvbnm3230@mail.ru>, Spiros Georgaras <sng@hellug.gr>, Vladislav <ivladislavefimov@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.

13 августа 2020 г. GNU