为何MinGW-w64中scanf支持%m$格式符,而printf却不支持?
MinGW-w64中scanf与printf对%m$格式符的支持差异原因
现象说明
在MinGW-w64环境中,scanf(即__mingw_scanf)支持使用%m$格式符指定参数位置:
int a, b; scanf("%2$d%1$d", &a, &b);
当输入1 2并回车时,变量a的值为2,b的值为1,完全符合%m$格式符的预期行为。
但同样的%m$格式符用在printf(即__mingw_printf)时却完全失效:
printf("%2$d %1$d\n", 123, 456);
这段代码编译、链接过程无任何错误或警告,但运行时不会输出预期的456 123,而是直接在控制台打印%2$d %1$d,将整个格式字符串当作普通文本处理。
原因解析
出现这种差异的核心在于MinGW-w64对两个函数的底层实现不同:
__mingw_scanf本质是直接调用微软MSVCRT(Microsoft C Runtime Library)中的scanf函数,而MSVCRT的scanf实现支持POSIX标准定义的%m$位置参数格式,因此能正常解析并工作。- 默认的
__mingw_printf是MinGW-w64基于newlib自行实现的版本,这个实现并未支持%m$这类位置参数格式。当它遇到%2$d这类无法识别的格式序列时,不会触发错误,而是直接将整个序列作为普通字符输出。
如果需要让printf支持%m$格式,可以改用MSVCRT的printf实现,比如调用__ms_printf函数,或者在编译时指定链接msvcrt库。
内容的提问来源于stack exchange,提问作者stanchcorder6
相关产品推荐
相关产品推荐

