.TH MPU_PRINTF 3 "Сентябрь 2026" "libmpuio" "Руководство программиста LIBMPUIO" .SH ИМЯ mpu_printf, mpu_fprintf, mpu_sprintf, mpu_snprintf, mpu_asprintf, mpu_dprintf, mpu_vprintf, mpu_vfprintf, mpu_vsprintf, mpu_vsnprintf, mpu_vasprintf, mpu_vdprintf, mpu_printf_unlocked, mpu_fprintf_unlocked, mpu_vprintf_unlocked, mpu_vfprintf_unlocked \- форматированный вывод UCS-2, включая числа libmpu произвольной точности .SH ОБЗОР .nf #include int mpu_printf( const __mpu_char16_t *format, ... ); int mpu_fprintf( mpu_FILE *stream, const __mpu_char16_t *format, ... ); int mpu_sprintf( __mpu_char16_t *string, const __mpu_char16_t *format, ... ); int mpu_snprintf( __mpu_char16_t *string, size_t size, const __mpu_char16_t *format, ... ); int mpu_asprintf( __mpu_char16_t **string, const __mpu_char16_t *format, ... ); int mpu_dprintf( int fd, const __mpu_char16_t *format, ... ); int mpu_vprintf( const __mpu_char16_t *format, va_list args ); int mpu_vfprintf( mpu_FILE *stream, const __mpu_char16_t *format, va_list args ); int mpu_vsprintf( __mpu_char16_t *string, const __mpu_char16_t *format, va_list args ); int mpu_vsnprintf( __mpu_char16_t *string, size_t size, const __mpu_char16_t *format, va_list args ); int mpu_vasprintf( __mpu_char16_t **string, const __mpu_char16_t *format, va_list args ); int mpu_vdprintf( int fd, const __mpu_char16_t *format, va_list args ); int mpu_printf_unlocked( const __mpu_char16_t *format, ... ); int mpu_fprintf_unlocked( mpu_FILE *stream, const __mpu_char16_t *format, ... ); int mpu_vprintf_unlocked( const __mpu_char16_t *format, va_list args ); int mpu_vfprintf_unlocked( mpu_FILE *stream, const __mpu_char16_t *format, va_list args ); .fi .SH ОПИСАНИЕ Семейство .B mpu_printf() формирует форматированный текст из строки формата UCS-2. .B mpu_printf() и .B mpu_vprintf() пишут в .BR mpu_stdout . .B mpu_fprintf() и .B mpu_vfprintf() пишут в указанный .BR mpu_FILE . .B mpu_sprintf() и .B mpu_vsprintf() пишут в неограниченную строку памяти UCS-2, предоставленную вызывающей стороной. .B mpu_snprintf() и .B mpu_vsnprintf() записывают не более .I size кодовых единиц UCS-2, включая завершающий ноль. .PP Для потоков реальных файлов текст UCS-2, созданный formatter, кодируется потоковым слоем в UTF-8. Назначения в памяти/строках остаются UCS-2. .PP .B mpu_asprintf() и .B mpu_vasprintf() выделяют через .BR malloc (3) достаточно большой NUL-терминированный результат UCS-2. При успехе они сохраняют указатель через .IR string ; вызывающая сторона освобождает его через .BR free (3). Если операция завершается ошибкой, .I *string устанавливается в NULL. .PP .B mpu_dprintf() и .B mpu_vdprintf() пишут форматированный текст в существующий POSIX-файловый дескриптор. Дескриптор не закрывается, владение остаётся у вызывающей стороны. Текст кодируется в UTF-8 по тем же правилам внешнего представления, что и для обычного файлового потока LIBMPUIO на основе дескриптора. .PP Обычный синтаксис преобразований следует соглашениям printf. LIBMPUIO расширяет его преобразованиями целых, вещественных и комплексных объектов libmpu произвольной точности. .SH ФОРМАТ СТРОКИ ФОРМАТА Обычные символы в .I format копируются без изменений. Спецификация преобразования начинается с .B % и имеет вид .PP .nf %[flags][width][.precision][.expdigits][length-or-Zbits]conversion .fi .PP Поле .B .expdigits \- расширение LIBMPUIO, используемое преобразованиями вещественных и комплексных чисел MPU. Оно не является частью обычного синтаксиса printf языка C. .PP Литерал знака процента выводится через .BR %% . .SH ФЛАГИ Распознаются следующие флаги. .TP .B - Выравнивать преобразованное значение по левому краю поля. Флаг .B 0 игнорируется при наличии .BR - . .TP .B + Всегда выводить знак для знаковых числовых преобразований. .TP .B " " Добавлять пробел перед положительным знаковым числовым значением. Флаг .B + имеет приоритет. .TP .B # Выбрать альтернативную форму. Для восьмеричного вывода она обеспечивает начальный ноль. Для шестнадцатеричного вывода ненулевое значение получает .B 0x или .BR 0X . Для двоичных .B b/B ненулевое значение получает .B 0b или .BR 0B . Для обычных вещественных преобразований флаг имеет стандартный printf-смысл альтернативной формы. Для общего формата MPU он также запрещает удаление незначащих завершающих нулей дробной части и десятичной точки. .TP .B 0 Дополнять числовые поля нулями вместо пробелов, когда это применимо. Для целочисленных преобразований флаг игнорируется при наличии явной точности. .SH ШИРИНА ПОЛЯ Десятичное число задаёт минимальную ширину поля. При необходимости преобразованное значение дополняется, но никогда не усекается только ради соблюдения ширины. .PP Ширина .B * берётся из следующего аргумента типа .BR int . Отрицательная ширина трактуется как положительная ширина вместе с флагом .BR - . .SH ТОЧНОСТЬ Точность начинается с точки. После неё может следовать десятичное целое или .BR * . Отрицательная точность, переданная через .BR * , трактуется так, как если бы точность вообще не была указана. .PP Для .B d, i, u, o, x, X, b и .B B точность задаёт минимальное число цифр. Целое значение ноль при точности ноль не выводит цифр с учётом правил альтернативной формы. .PP Для .B s точность задаёт максимальное число символов UCS-2, выводимых из строки. Точность не влияет на .BR c . .PP Для обычных вещественных преобразований точность имеет стандартный printf- смысл. Для вещественных преобразований MPU см. раздел .B ПРЕОБРАЗОВАНИЯ ВЕЩЕСТВЕННЫХ ЧИСЕЛ MPU ниже. .SH МОДИФИКАТОРЫ ДЛИНЫ Для обычных целочисленных преобразований поддерживаются следующие модификаторы длины. .TP .B hh Аргумент преобразуется как .B signed char или .BR unsigned char . .TP .B h Аргумент преобразуется как .B short или .BR unsigned short . .TP .B l Аргумент имеет тип .B long или .BR unsigned long . Для обычного вещественного вывода, как и в C printf, .B l не изменяет продвинутый аргумент .BR double . .TP .B ll Аргумент имеет тип .B long long или .BR unsigned long long . .TP .B j Аргумент имеет тип .B intmax_t или .BR uintmax_t . Для .B %n при использовании .B j аргумент имеет тип .BR intmax_t\ * . .TP .B t Аргумент имеет тип .B ptrdiff_t или соответствующую беззнаковую интерпретацию. .TP .B L Для обычных вещественных преобразований аргумент имеет тип .BR "long double" . .PP Стандартный модификатор длины C .B z намеренно не реализован. В LIBMPUIO и .B z, и .B Z вводят описанный ниже модификатор размера LibMPU. .PP Буква .B j также обозначает историческое комплексное преобразование MPU. Она трактуется как стандартный модификатор длины .B intmax_t, если после неё следует обычное целочисленное преобразование или .BR n ; в остальных случаях это комплексное преобразование MPU. .SH ОБЫЧНЫЕ ПРЕОБРАЗОВАНИЯ .TP .B d, i Вывести знаковое десятичное целое. .TP .B u Вывести беззнаковое десятичное целое. .TP .B o Вывести беззнаковое целое в восьмеричном виде. .TP .B x, X Вывести беззнаковое целое в шестнадцатеричном виде. Цифры и префикс альтернативной формы используют нижний регистр для .B x и верхний для .BR X . .TP .B b, B Расширение LIBMPUIO: вывести беззнаковое целое в двоичном виде. С .B # ненулевое значение получает .B 0b или .BR 0B . .TP .B c Вывести один символ UCS-2. Поскольку символьный I/O LIBMPUIO использует UCS-2, аргумент имеет тип .B int, значение которого преобразуется в .BR __mpu_char16_t . Это не многобайтовое/wchar_t-преобразование libc. .TP .B s Вывести NUL-терминированную строку UCS-2 типа .BR "const __mpu_char16_t *" . Точность ограничивает число выводимых символов UCS-2. NULL-указатель выводится как .BR (null) . .TP .B a Расширение LIBMPUIO: вывести NUL-терминированную многобайтовую строку текущей локали типа .BR "const __mpu_char8_t *" . Байтовая строка декодируется согласно активной локали .B LC_CTYPE и преобразуется в строгий UCS-2 до попадания в поток LIBMPUIO. Ширина поля и точность измеряются в преобразованных символах UCS-2. NULL-указатель выводится как .BR (null) . Некорректная многобайтовая последовательность, суррогат или символ вне модели UCS-2 приводят к ошибке преобразования .BR EILSEQ . Модификаторы длины и MPU-модификатор .B z/Z к этому преобразованию не применяются. .TP .B p Вывести значение указателя в шестнадцатеричной альтернативной форме. Тип аргумента \- .BR "void *" . .TP .B n Записать число символов UCS-2, сформированных к этому моменту, через аргумент- указатель. Это преобразование само не выводит символов. Тип указателя выбирается модификатором длины: без модификатора используется .BR int\ * ; .B hh, h, l, ll, j и .B t выбирают соответствующие целочисленные типы указателей. .TP .B f, F Вывести обычный .B double (или .B long double с .BR L ) в фиксированном формате. .TP .B e, E Вывести обычное вещественное значение в научной нотации. .TP .B g, G Вывести обычное вещественное значение в общем формате. .PP Обычный вывод .B f/F/e/E/g/G делегируется правилам форматирования libc хост-системы и потому следует активному символу десятичного разделителя .BR LC_NUMERIC . LIBMPUIO декодирует полученное многобайтовое поле libc в строгий UCS-2 до передачи в поток LIBMPUIO; некорректные последовательности, суррогатный вывод или символы вне модели UCS-2 отвергаются с .BR EILSEQ . Соответствующие обычные преобразования scanf используют то же соглашение о десятичном разделителе локали. Грамматика форматированных чисел MPU .B z/Z отделена от этого обычного поведения локали C. .SH МОДИФИКАТОР РАЗМЕРА MPU Модификатор размера LibMPU для чисел произвольной точности имеет вид .B z или .BR Z . Строчная и прописная формы эквивалентны. Стандартный модификатор длины C .B z для .B size_t намеренно не является частью языка форматов LIBMPUIO. .PP Десятичное поле .I bits не является произвольным числом времени выполнения. Оно должно обозначать один из размеров MPU, скомпилированных в грамматику текущей сборки LIBMPUIO: .PP .nf 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536 .fi .PP В конкретной сборке существуют только значения, не превышающие .B MPU_REAL_IO_LIMIT из .BR . Например, если .B MPU_REAL_IO_LIMIT равен 16384, то модификаторы .B z32768, .B Z32768, .B z65536 и .B Z65536 в языке форматов этой сборки LIBMPUIO отсутствуют и приводят к ошибке формата. .PP Если после .B z или .BR Z не следуют десятичные цифры, предполагается 128 бит. Поэтому .B %zu является MPU-преобразованием 128-битного беззнакового целого и по размеру точно эквивалентно .BR %z128u ; это .B не преобразование .BR size_t . Аналогично, .B %zR, .B %ZR, .B %zJ и .B %ZJ используют размер MPU по умолчанию, равный 128 бит. .PP Модификатор размера разбирается до буквы преобразования. После принятия размера буква преобразования выбирает класс числа: целочисленные преобразования работают с целым объектом libmpu, вещественные \- с вещественным объектом libmpu, а .B j/J \- с комплексным объектом libmpu. Целочисленные преобразования принимают размеры MPU начиная с 8 бит; для вещественных и комплексных преобразований требуется не менее 32 бит. .PP .B MPU_MATH_FN_LIMIT не определяет грамматику форматированного I/O. Он ограничивает только трансцендентные/математические функции. Набор доступных модификаторов .B z/Z определяется .BR MPU_REAL_IO_LIMIT . .SH МОДЕЛЬ ТИПОВ АРГУМЕНТОВ Обычные преобразования C и преобразования MPU намеренно используют разные соглашения об аргументах. .PP Для обычного преобразования буква преобразования и стандартный модификатор длины описывают тип C, который должен извлечь .BR va_arg (). Аргумент передаётся по значению с обычными преобразованиям аргументов по умолчанию. Например: .PP .nf char k = 7; mpu_printf( MPU_UCS2("k = %d\n"), k ); .fi .PP Здесь .B k продвигается до .B int до попадания в список вариадических аргументов, а .B %d выбирает значение .BR int . Formatter не обнаруживает тип аргумента во время выполнения; строка формата сообщает ему, какой тип C извлекать. .PP Преобразование MPU, выбранное .B z или .BR Z , имеет другой контракт. Его аргумент \- указатель на хранилище объекта MPU, а модификатор размера точно сообщает formatter, сколько бит содержит этот объект. Для array typedef, используемых libmpu, имя объекта в аргументе вызова функции обычно подвергается стандартному преобразованию массива в указатель, поэтому естественная запись выглядит так: .PP .nf mpu_int128_t c; mpu_real128_t r; mpu_printf( MPU_UCS2("c = %z128u\n"), c ); mpu_printf( MPU_UCS2("r = %z128g\n"), r ); .fi .PP Сам указатель не несёт метаданных размера объекта. Поэтому вариадический formatter не может определить, указывает ли он, например, на 32-, 128- или 65536-битный объект MPU. Явное поле .B z/Z следовательно является частью типового контракта MPU-преобразования, а не избыточным украшением. .PP Технически возможно направить MPU-преобразование на хранилище обычного объекта C, если его точное представление и размер намеренно известны, например: .PP .nf char k = 7; mpu_printf( MPU_UCS2("k = %z8d\n"), &k ); .fi .PP Это низкоуровневая интерпретация байта по адресу .B &k как 8-битного целого объекта MPU; это .B не обычное соглашение вывода C .B char и не должно использоваться как переносимая замена .BR %d . Для многобайтовых объектов C такое использование дополнительно может зависеть от представления, порядка байтов и совместимости с хранилищем libmpu. Обычные объекты C обычно должны использовать обычные преобразования C; объекты MPU \- .BR z/Z . .PP Замена array typedef libmpu на structure typedef не сделала бы вариадическую функцию самоописывающейся. C .B va_list не несёт универсальных метаданных типа или размера времени выполнения, а .B va_arg() по-прежнему требует, чтобы ожидаемый тип был известен из контракта формата. .SH ЦЕЛОЧИСЛЕННЫЕ ПРЕОБРАЗОВАНИЯ MPU С .BR z/Z , .B d и .B i форматируют знаковое целое произвольной точности. Преобразования .B u, o, x, X, b и .B B форматируют беззнаковое целое произвольной точности. Аргумент является указателем на целый объект libmpu, размер хранилища которого соответствует выбранному числу бит. .PP Примеры: .PP .nf %Z128d %#Z256x %#Z1024B %08.3Z128d .fi .PP Formatter удаляет внутренний префикс основания libmpu до применения собственных правил альтернативной формы printf. Поэтому .B # имеет одинаковый внешне наблюдаемый смысл для обычного и MPU-целочисленного вывода. .SH ПРЕОБРАЗОВАНИЯ ВЕЩЕСТВЕННЫХ ЧИСЕЛ MPU Нативные вещественные преобразования MPU \- .B r и .BR R . Если явный модификатор .B z/Z не задан, используется 128 бит. .PP Буква преобразования выбирает регистр, однако маркер экспоненты, выводимый для вещественного числа, равен .B e для .B %r и .B E для .BR %R . Буквы .B r/R являются спецификаторами преобразования, а не печатаемым разделителем экспоненты вещественного числа. .PP Примеры: .PP .nf %Z128R %.28Z128R %.28.4Z128R .fi .PP Первая точность управляет числом цифр мантиссы. Необязательное второе поле .B .expdigits задаёт минимальную ширину экспоненты. Оно также может передаваться через .BR * . Например: .PP .nf %.4.3Z128e -> 1.2346e+004 .fi .PP Также поддерживаются MPU-формы .B z/Ze, .B z/ZE, .B z/Zf, .B z/ZF, .B z/Zg и .BR z/ZG . .PP Все эти вещественные преобразования извлекают указатель на вещественный объект libmpu выбранного размера. В частности, и .B %Z128R, и .B %Z128E ожидают объект .BR mpu_real128_t . Комплексный вывод отделён: .B %Z128J ожидает объект .BR mpu_complex128_t . Таким образом, соответствие типов имеет вид: .PP .nf %Z128R -> mpu_real128_t %Z128E -> mpu_real128_t %Z128J -> mpu_complex128_t .fi .PP Для исторической совместимости с CODE.LIB .B MPU f/F являются научными псевдонимами e/E; они не являются преобразованиями фиксированной точки. Это намеренно отличается от обычных C .BR %f/%F . .PP Для MPU .B g/G отсутствующая точность по умолчанию равна 6, а точность ноль трактуется как одна значащая цифра. Научная нотация выбирается, если десятичная экспонента меньше -4 или больше либо равна точности. В остальных случаях используется фиксированный стиль. Завершающие незначащие нули дробной части и десятичная точка удаляются, если не указан .BR # . .PP Строчная .B %a \- преобразование LIBMPUIO для многобайтовой строки текущей локали. .SH ПРЕОБРАЗОВАНИЯ КОМПЛЕКСНЫХ ЧИСЕЛ MPU Нативные комплексные преобразования MPU \- .B j и .BR J . Если явный размер MPU не задан, по умолчанию используется 128 бит. Аргумент является указателем на комплексный объект libmpu выбранного размера. .PP Действительная и мнимая компоненты объединяются в историческом комплексном представлении MPU. Например: .PP .nf %.20.4Z128J -> 1.25000000000000000000R+0000-2.50000000000000000000J+0000 .fi .PP Для .B %j маркеры экспонент компонентов \- .B r и .BR j . Для .B %J они равны .B R и .BR J . Этот исторический комплексный синтаксис намеренный. Он отличается от вещественных .BR %r/%R , у которых печатаемый маркер экспоненты \- .BR e/E . .PP Если флаг .B 0 используется вместе с полем, ширина которого больше длины сформированного комплексного значения, свободная часть поля делится поровну между действительной и мнимой компонентами. Нули вставляются после знака каждой компоненты. Если свободная ширина нечётна, один оставшийся символ выводится как обычный ведущий пробел. Например, для значения с компонентами 1.25 и 2.5: .PP .nf %+040.6.3Z128J -> +0000001.250000R+000+0000002.500000J+000 %+039.6.3Z128J -> +000001.250000R+000+000002.500000J+000 .fi .SH СТРОКОВЫЙ ВЫВОД И УСЕЧЕНИЕ .B mpu_sprintf() и .B mpu_vsprintf() не знают ёмкость назначения. Вызывающая сторона обязана предоставить достаточно хранилища UCS-2 для полного результата и завершающего нуля. .PP .B mpu_snprintf() и .B mpu_vsnprintf() записывают не более .I size кодовых единиц UCS-2, включая завершающий ноль. Если .I size равен нулю, данные назначения не записываются. Возвращаемое значение \- число символов UCS-2, которое было бы сформировано при достаточном пространстве, без завершающего нуля. .SH БЛОКИРОВКА Обычные потоковые варианты блокируют .B mpu_FILE на время форматирования. Варианты .B *_unlocked не захватывают mutex потока. Они предназначены для кода, который уже сериализовал доступ, обычно через .BR mpu_flockfile (3): .PP .nf mpu_flockfile( fp ); mpu_fprintf_unlocked( fp, fmt, ... ); mpu_fflush_unlocked( fp ); mpu_funlockfile( fp ); .fi .PP Функции строкового вывода используют приватные потоки памяти и не имеют публичных unlocked-вариантов. .SH ОПРЕДЕЛЕНИЕ РАЗМЕРА И УСЕЧЕНИЕ SNPRINTF Для .B mpu_snprintf() и .BR mpu_vsnprintf () аргумент .I size \- ёмкость массива назначения UCS-2, включая конечный символ NUL. Если .I size равен нулю, символы назначения не сохраняются, а .I string может быть NULL. Функции всё равно полностью разбирают формат и возвращают число символов UCS-2, которое было бы сформировано, без конечного NUL. Это позволяет использовать обычную двухпроходную схему выделения памяти. .PP При усечении вывода возвращаемое значение и любое преобразование .B %n используют логическое число символов, а не число символов, реально поместившихся в массив назначения. .PP Если логическое число символов форматированного вывода не представимо типом .BR int , операция завершается с отрицательным возвращаемым значением и .B errno, установленным в .BR EOVERFLOW . .SH ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ При успехе эти функции возвращают число сформированных символов UCS-2 без завершающего нуля, используемого строковыми назначениями. Для .BR mpu_asprintf () и .BR mpu_vasprintf () это число выделенных кодовых единиц UCS-2 до завершающего NUL. Для .BR mpu_dprintf () и .BR mpu_vdprintf () счётчик по-прежнему измеряется в символах UCS-2, а не в числе байтов UTF-8, записанных в дескриптор. Отрицательное значение означает ошибку. .PP .B %n не выводит символов; оно лишь сохраняет счётчик, накопленный к этому моменту. .SH ОШИБКИ Ошибки нижележащего потока и выделения памяти сообщаются отрицательным возвращаемым значением и, где применимо, .BR errno . .B mpu_asprintf() и .B mpu_vasprintf() сообщают об ошибке выделения памяти через .BR ENOMEM ; NULL-указатель назначения отвергается с .BR EINVAL . .B mpu_dprintf() и .B mpu_vdprintf() могут сообщать ошибки дескриптора и записи, например .BR EBADF . Недопустимый настроенный размер MPU приводит к ошибке с .BR EINVAL . Строгая файловая граница UCS-2 может возвращать .B EILSEQ, если символ не может быть представлен по правилам UCS-2/UTF-8 LIBMPUIO. .SH ПРИМЕРЫ Строка UCS-2 и обычные значения: .PP .nf __mpu_char16_t fmt[] = MPU_UCS2("name=%s value=%08x"); __mpu_char16_t name[] = MPU_UCS2("mpu"); mpu_printf( fmt, name, 0x1234U ); .fi .PP Многобайтовая строка текущей локали: .PP .nf __mpu_char8_t name8[] = "Andrey"; mpu_printf( MPU_UCS2("name=%a\n"), name8 ); .fi .PP Целое произвольной точности: .PP .nf __mpu_char16_t fmt[] = MPU_UCS2("%#Z256x"); mpu_printf( fmt, &integer256 ); .fi .PP 128-битное вещественное число с 28 цифрами мантиссы и четырьмя цифрами экспоненты: .PP .nf __mpu_char16_t fmt[] = MPU_UCS2("%.28.4Z128E"); mpu_fprintf( fp, fmt, &real128 ); .fi .SH СТРОКОВЫЕ ЛИТЕРАЛЫ UCS-2 Публичный макрос .B MPU_UCS2() формирует нативный 16-битный строковый литерал с помощью префикса языка .BR u"..." . Например: .PP .nf mpu_printf( MPU_UCS2( "value=%d" ), value ); .fi .PP В отличие от .BR L"..." , использующего платформенный тип .BR wchar_t , .B MPU_UCS2() предназначен для интерфейсов LIBMPUIO, текстовые аргументы которых используют тип LIBMPU .BR __mpu_char16_t . .PP Публичный заголовок включает эту возможность, когда режим трансляции предоставляет 16-битные строковые литералы .BR u"..." : C11 или новее, C++11 или новее либо режим GNU C, поддерживающий это расширение. Конфигурация сборки также может определить .B MPU_HAVE_UCS2_STRING_LITERALS до включения .B , явно указывая доступность возможности. Если она недоступна, публичный заголовок выдаёт ошибку времени компиляции. .PP Префикс литерала является возможностью исходного языка, а не переключателем кодировки времени выполнения. LIBMPUIO по-прежнему применяет строгие правила UCS-2 и отвергает суррогатные кодовые единицы с .BR EILSEQ . .SH ПРИМЕЧАНИЯ LIBMPUIO использует внутри 16-битный UCS-2, а не платформенный тип .BR wchar_t . Поэтому .B %c и .B %s работают непосредственно с символами и строками UCS-2 и не имеют многобайтовой семантики libc .BR %lc/%ls . Преобразование LIBMPUIO .B %a является явным интерфейсом многобайтовой строки текущей локали; тип его аргумента \- .BR "const __mpu_char8_t *" . .PP Строгий UCS-2 не может представлять скалярные значения Unicode выше U+FFFF. Текстовый слой не представляет такой ввод парами суррогатов. .SH СМ. ТАКЖЕ .BR mpu_scanf (3), .BR mpu_flockfile (3), .BR mpu_unlocked (3), .BR mpu_fopen (3), .BR libmpuio (3) .SH ЛОКАЛЬ Для обычных преобразований с плавающей точкой символ десятичной точки следует активной локали C так же, как в системном семействе .BR printf (3). Следовательно, локаль, в которой .B LC_NUMERIC использует запятую, может, например, вывести .B 1,50 для .BR %.2f . Регрессионный набор LIBMPUIO выбирает локаль C после инициализации libmpu, чтобы ожидаемые строки были воспроизводимыми. .SH ПЕРЕПОЛНЕНИЕ ПАРСЕРА ФОРМАТА Парсер формата обнаруживает переполнение при десятичном накоплении ширины поля, точности, расширения ширины экспоненты LIBMPU и полей размера z/Z. Он также отвергает INT_MIN, переданный как отрицательная ширина поля через *, поскольку это значение нельзя представить как положительную ширину int. Эти случаи завершаются с отрицательным возвращаемым значением и устанавливают errno в EOVERFLOW. .SH БЛОКИРУЕМЫЙ И UNLOCKED-ФОРМАТИРОВАННЫЙ ВЫВОД .BR mpu_fprintf_unlocked (), .BR mpu_vfprintf_unlocked (), .BR mpu_printf_unlocked () и .BR mpu_vprintf_unlocked () используют ровно тот же formatter, что и обычные потоковые формы, но не выполняют неявную блокировку потока. Разбор формата, обработка MPU z/Z, поведение локали, %n, логические счётчики вывода, правила усечения и ошибки не изменяются. .PP Семейства sprintf/snprintf пишут в память UCS-2, принадлежащую вызывающей стороне, а не в поток mpu_FILE, и потому не имеют stream-unlocked вариантов.