jam*_*lin 178
大多数这些答案的解释%n 呢(这是打印不信邪,写迄今为止打印到一个字符数int变量),但至今没有人真正给出了什么样的例子使用它.这是一个:
int n;
printf("%s: %nFoo\n", "hello", &n);
printf("%*sBar\n", n, "");
Run Code Online (Sandbox Code Playgroud)
将打印:
hello: Foo
Bar
Run Code Online (Sandbox Code Playgroud)
与Foo和Bar对齐.(如果不使用%n这个特定的例子,这样做是微不足道的,一般来说,总是可以打破第一次printf调用:
int n = printf("%s: ", "hello");
printf("Foo\n");
printf("%*sBar\n", n, "");
Run Code Online (Sandbox Code Playgroud)
稍微增加的便利性是否值得使用类似的东西%n(并且可能引入错误)值得商榷.)
Sta*_*key 145
什么都没打印.参数必须是指向signed int的指针,其中存储了到目前为止写入的字符数.
#include <stdio.h>
int main()
{
int val;
printf("blah %n blah\n", &val);
printf("val = %d\n", val);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
以前的代码打印:
blah blah
val = 5
Run Code Online (Sandbox Code Playgroud)
Xzh*_*hsh 18
我还没有真正看到%n说明符的许多实际的现实世界用途,但我记得它在oldschool printf漏洞中使用了很长一段时间的格式字符串攻击.
有点像这样的东西
void authorizeUser( char * username, char * password){
...code here setting authorized to false...
printf(username);
if ( authorized ) {
giveControl(username);
}
}
Run Code Online (Sandbox Code Playgroud)
恶意用户可以利用username参数作为格式字符串传递给printf并使用组合%d,%c或者w/e通过调用堆栈,然后修改授权为真值的变量.
是的,它是一种深奥的用法,但是在编写守护进程以避免安全漏洞的时候总是有用的吗?:d
KLe*_*ee1 13
从这里我们看到它存储了到目前为止打印的字符数.
n参数应该是一个指向整数的指针,该整数写入到目前为止通过调用其中一个fprintf()函数写入输出的字节数.没有参数被转换.
一个示例用法是:
int n_chars = 0;
printf("Hello, World%n", &n_chars);
Run Code Online (Sandbox Code Playgroud)
n_chars然后会有一个值12.
到目前为止,所有答案都是关于这%n一点,但不是为什么有人会首先想要它.我发现它对于sprintf/ 稍有用snprintf,当你可能需要稍后分解或修改结果字符串时,因为存储的值是结果字符串中的数组索引.然而,这个应用程序更有用,sscanf特别是因为系列中的函数scanf不返回已处理的字符数而是字段数.
另一个真正的hackish使用是在同时打印一个数字作为另一个操作的一部分时免费获得伪log10.
前几天,我发现自己处在%n可以很好地解决我的问题的境地。与之前的答案不同,在这种情况下,我无法设计出一个好的选择。
我有一个显示某些指定文本的GUI控件。该控件可以用粗体(或斜体或带下划线等)显示该文本的一部分,我可以通过指定开始和结束字符索引来指定哪个部分。
就我而言,我正在使用生成文本到控件snprintf,并且我希望将其中一种替换内容设为粗体。找到此替换的开始和结束索引并非易事,因为:
该字符串包含多个替换项,替换项之一是用户指定的任意文本。这意味着对我所关心的替换进行文本搜索可能很含糊。
格式字符串可能已本地化,并且可能将$POSIX扩展名用于位置格式说明符。因此,在原始格式字符串中搜索格式说明符本身并非易事。
本地化方面也意味着我不能轻易将格式字符串分解为多个对的调用snprintf。
因此,找到围绕特定替换的索引的最直接方法是:
char buf[256];
int start;
int end;
snprintf(buf, sizeof buf,
"blah blah %s %f yada yada %n%s%n yakety yak",
someUserSpecifiedString,
someFloat,
&start, boldString, &end);
control->set_text(buf);
control->set_bold(start, end);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
97440 次 |
| 最近记录: |