Ale*_*lio 2 c printf specifier
这是我的代码:
#include <stdio.h>
int main(void) {
int n;
fprintf(stdout, "Hello%n World\n", &n);
fprintf(stdout, "n: %d\n", n);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是我的输出:
Hellon: 0
Run Code Online (Sandbox Code Playgroud)
fprintf格式说明符"%n"不起作用?ISO/IEC 9899:201x C11 - 7.21.6.1 - fprintf功能
转换说明符及其含义是:
(......)
%n参数应该是一个指向有符号整数的指针,其中写入到目前为止通过调用fprintf写入输出流的字符数.没有参数被转换,但是消耗了一个参数.如果转换规范包括任何标志,字段宽度或精度,则行为未定义....
(......)
这是我在Code :: Blocks上使用的编译器版本:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=C:/Program\ Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev
0/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-8.1.0/configure --host=x86_64-w64-mingw32 --bu
ild=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysr
oot=/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64 --enable-shared --enable
-static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdc
xx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-
lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --
enable-version-specific-runtime-libs --disable-libstdcxx-pch --disable-libstdcxx
-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls
--disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=noco
na --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw810/p
rerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw810/prerequisites/x86
_64-w64-mingw32-static --with-mpc=/c/mingw810/prerequisites/x86_64-w64-mingw32-s
tatic --with-isl=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-pkgv
ersion='x86_64-posix-seh-rev0, Built by MinGW-W64 project' --with-bugurl=https:/
/sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/x
86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x
86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/
include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/x86_64-810-posix-seh-rt_v6
-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include
-I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS=' -I/c/
mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prere
quisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw
32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw810/x86_64-810-posix-seh-
rt_v6-rev0/mingw64/opt/lib -L/c/mingw810/prerequisites/x86_64-zlib-static/lib -L
/c/mingw810/prerequisites/x86_64-w64-mingw32-static/lib '
Thread model: posix
gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)
Run Code Online (Sandbox Code Playgroud)
如Microsoft文档中所述%n,默认情况下在MinGW系统上使用的Microsoft C库中禁用:
重要
由于
%n格式本质上不安全,因此默认情况下禁用该格式.如果%n在格式字符串中遇到,则调用无效参数处理程序,如参数验证中所述.要启用%n支持,请参阅_set_printf_count_output.
%n微软声称是否真的不安全是值得商榷的.显示支持此声明的示例将此printf功能与使用可变格式字符串相结合,该字符串可由攻击者通过缓冲区溢出错误进行更改.
在某些Microsoft系统上,您可以通过以下方式修复程序:
#include <stdio.h>
int main(void) {
int n;
_set_printf_count_output(1);
fprintf(stdout, "Hello%n World\n", &n);
fprintf(stdout, "n: %d\n", n);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
对于更便携的方法:您可以使用解决方法来避免使用%n并仍然获得相同的结果:
#include <stdio.h>
int main(void) {
int n;
n = fprintf(stdout, "Hello");
fprintf(stdout, " World\n");
fprintf(stdout, "n: %d\n", n);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
Hello World
n: 5
Run Code Online (Sandbox Code Playgroud)