在 printf 系列函数中,下列哪个格式化占位符有可能导致内存任意写风险 [A]
A. %n
B. %d
C. %p
D. %s
使用printf修改变量的值 —— VS2008中使用%n输出遇到的问题及解决方法
#include <stdio.h>
int main(void)
{
int e;
int i = 0;
e = _set_printf_count_output(1);
printf( "%%n support was %sabled.\n", e ? "en" : "dis");
printf( "%%n support is now %sabled.\n", _get_printf_count_output() ? "en" : "dis");
printf( "12345%n6789\n", &i); // %n format should set i to 5
printf( "i = %d\n", i);
return 0;
}
调用_set_printf_count_output函数可以打开%n使能,
#include <stdio.h>
int main(void)
{
printf("_get_printf_count_output is %d\n", _get_printf_count_output()); // 0
printf("_set_printf_count_output is %d\n", _set_printf_count_output(1)); // 0
printf("_get_printf_count_output is %d\n", _get_printf_count_output()); // 1
printf("_set_printf_count_output is %d\n", _set_printf_count_output(1)); // 1
printf("_get_printf_count_output is %d\n", _get_printf_count_output()); // 1
return 0;
}
_set_printf_count_output函数返回当前的printf_count_output结果
以下代码输入结果为
int main(void)
{
_set_printf_count_output(1);
char c;
short s;
int i;
long l;
long long ll;
// 最初转换指示符%n是用来帮助排列格式化输出字符串的. 它将字符数目成功地输出到以参数的形式提供的整数地址中
printf("hello %hhn.", &c);
printf("hello %hn.", &s);
printf("hello %n.", &i);
printf("hello %ln.", &l);
printf("hello %lln.\n", &ll);
fprintf(stdout, "c: %hhd, s: %hd, i: %d, l: %ld, ll: %lld\n", c, s, i, l, ll); // 6
return 0;
}
以下代码输入结果为
int main(void)
{
char* insertTime = "2021";
printf("|%-15s|\n",insertTime); //左对齐,15位长度,不够补空格
printf("|%15s|\n",insertTime); //右对齐,15位长度,不够补空格
printf("|%015s|\n",insertTime); //右对齐,15位长度,不够补0
printf("|%-15.2f|\n",atof(insertTime)); //左对齐,15位长度,带两位小数,不够补空格
float f=123.456;
printf("%f \n",f);
printf("%10.1f \n",f);
printf("%5.1f \n",f);
printf("%10.3faaa \n",f);
printf("%-10.3faaa \n",f);
printf("%g \n",f);
return 0;
}
|2021 |
| 2021|
|000000000002021|
|2021.00 |
123.456001
123.5
123.5
123.456aaa
123.456 aaa
123.456
%[标志][宽度][.精度][{长度修饰符}] 转换指示符
例如,对转换规范%-10.8ld来说,-是标志位,10代表宽度,8代表精度,字面l是长度修饰符,d是转换指示符。这个转换规范将一个long int型的参数按照十进制格式打印,在一个最小宽度为10个字符的域中保持最少8位左对齐。每一个域都是代表特定格式选项的单个字符或数字。最简单的转换规范仅仅包含一个”%”和一个转换指示符(例如%s)。
转换指示符:用来指示所应用的转换类型。它是唯一必须的格式域,出现在任意可选格式域之后。下表中列举了C标准中的一些转换指示符:
标志:标志位用来调整输出和打印的符号、空白、小数点、八进制和十六进制前缀等。一个格式规范中可能包含一个或多个标志。
宽度:是一个用来指定输出字符的最小个数的十进制非负整数。如果输出的字符个数比指定的宽度小,就用空白字符补足。如果指定的宽度较小也不会引起输出域的截断。如果转换的结果比域宽大,则域会被扩展以容纳转换结果。如果使用星号(*)来指定宽度,则宽度将由参数列表中的一个int型的值提供。在参数列表中,宽度参数必须置于被格式化的值之前。
精度:是用来指示打印字符个数、小数位或者有效数字个数的非负十进制整数。与宽度域不同,精度域可能会引起输出的截断或浮点值的舍入。如果精度值被设为0并且被转换值也为0,则不会输出任何字符。如果精度域是一个星号(*),那么它的值就由参数列表中的一个int参数提供。在参数列表中,精度参数必须置于被格式化的值之前。
长度修饰符:指定了参数的大小。下表列举了长度修饰符及其对应的含义。如果使用了表中未出现的长度修饰符和转换指示符的组合,则会导致未定义的行为:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)