C標準ライブラリscanf
関数の書式指定%s
において、取得先の文字列バッファを動的確保する機能拡張。
// POSIX準拠システム char *s = NULL; scanf("%ms", &s); // sはmallocで確保される ... free(s);
まとめ:
- 標準C(ISO C):該当機能は存在しない。メモリ領域を事前確保し、書式指定
%s
には領域サイズを指定すること。*1 - POSIX準拠システム:動的メモリ確保を行うオプション文字
m
が存在する。 - LSB準拠システム:動的メモリ確保を行うオプション文字
a
が存在するが、これはC99標準の16進浮動小数点%a
指定と衝突する。*2
POSIX
オプション文字m
はThe Open Group Base Specifications Issue 6/IEEE Std 1003.1-2008で追加*3されている。POSIX規格(IEEE Std 1003.1-2013)より引用。
The
The Open Group Base Specifications Issue 7, fscanf, scanf, sscanf - convert formatted input%c
,%s
, and%[
conversion specifiers shall accept an optional assignment-allocation character'm'
, which shall cause a memory buffer to be allocated to hold the string converted including a terminating null character. In such a case, the argument corresponding to the conversion specifier should be a reference to a pointer variable that will receive a pointer to the allocated buffer. The system shall allocate a buffer as if malloc() had been called. The application shall be responsible for freeing the memory after usage. If there is insufficient memory to allocate a buffer, the function shall set errno to [ENOMEM] and a conversion error shall result. If the function returns EOF, any memory successfully allocated for parameters using assignment-allocation character'm'
by this call shall be freed before the function returns.
Linux Standard Base(LSB)
LSB 5.0 Core specificationより引用。
Description
The scanf() family of functions shall behave as described in POSIX 1003.1-2008 (ISO/IEC 9945-2009), except as noted below.
Differences
The%s
,%S
and%[
conversion specifiers shall accept an option length modifiera
, which shall cause a memory buffer to be allocated to hold the string converted. In such a case, the argument corresponding to the conversion specifier should be a reference to a pointer value that will receive a pointer to the allocated buffer. If there is insufficient memory to allocate a buffer, the function may seterrno
to ENOMEM and a conversion error results.Note: This directly conflicts with the ISO C (1999) usage of
Linux Standard Base Core Specification, 14.5. Interface Definitions for libc, scanf%a
as a conversion specifier for hexadecimal float values. While this conversion specifier should be supported, a format specifier such as"%aseconds"
will have a different meaning on an LSB conforming system.
Linux/glibcライブラリのマニュアルには本件に関するノートが存在し、m
オプション(POSIX準拠)の利用が推奨されている。
'a' 代入割り当て(assignment-allocation)修飾子
元々、GNU Cライブラリ(glibc)では、a 文字による文字列入力に対する動的割り当て変換指定子(dynamic allocation conversion specifier)を (非標準の拡張として) サポートしている。この機能は少なくとも glibc 2.0 の時点ではすでに存在している。(略)a 修飾子は gcc -std=c99 や gcc -D_ISOC99_SOURCE でコンパイルしたプログラムでは (_GNU_SOURCE も同時に指定していない場合) 利用できない点に注意。この場合、a は (上述の通り) 浮動小数点数を示す変換指定子と解釈される。
m 修飾子への対応はバージョン 2.7 以降の glibc で追加されている。新しいプログラムでは a の代わりに m を使用すべきである。
https://linuxjm.osdn.jp/html/LDP_man-pages/man3/scanf.3.html
関連URL
*1:バッファオーバーランによるセキュリティホール回避措置。JPCERT STR35-C参照。
*2:scanf関数ファミリへの書式指定子では a, e, f, g に機能的な差異はない。(C99 7.19.6.2/p12)
*3:http://www.opengroup.org/austin/aardvark/latest/xshbug2.txt "Enhancement Request Number 132"