如果我使用printf(“one \ 0two”),会发生什么情况;?
问题描述:
由于暗示的标题,什么的意思,如果我做这在C++得到印刷:如果我使用printf(“one 0two”),会发生什么情况;?
?当我这样做时,GCC给了我一个警告,但是visual studio对它很好。他们的工作方式有什么不同?考虑一下,我期望printf在第一个\ 0处停下来,但显然这个代码使用到现在一直在windows上工作正常,所以我不确定。
答
您将获得:
$ a.out
one$
的\0
是一个空结束的字符串。没有换行符。
$ cat try.c
#include <stdio.h>
int
main(){
printf("one\0two");
return 0;
}
542 $ gcc try.c
try.c: In function ‘main’:
try.c:5: warning: embedded ‘\0’ in format
543 $ ./a.out
one544 $
答
C样式的字符串以NULL结尾。所以当打印一个字符串时,它会打印所有内容,直到第一次出现空字符。在这种情况下,它应该打印one
而没有别的。
答
你得到'一'打印 - 后面没有换行符。
您还收到编译器警告。
海湾合作委员会正在善待 - 让你知道'两'是无关紧要的。 您也不应该使用使用printf()
的格式字符串中没有%
标记是没有意义的...您可以使用puts()
或fputs()
来代替。由于安全原因,不使用用户可以选择的格式字符串至关重要:char *s = ...; printf(s);
。
MSVS在没有给你警告的时候没有错;编译器没有义务建议修复代码的方法。
答
printf
的确会停在嵌入的“空”字符处,而只是打印“一个”。
GCC发出警告,因为这样的格式字符串很可能是错误的;它还会将格式字符串与参数类型进行比较,如果不匹配则发出警告。其他编译器不会花费太多精力来分析诸如printf
之类的函数的参数,并且会在没有任何警告的情况下让有缺陷的参数通过。
“你也不应该使用printf()和一个没有%标记的格式字符串”:这对我来说是新的!为什么不是?我一直这样做。也许你的意思是你不应该使用'printf(s)'来打印任意字符串(可能包含%标记)?我同意这一点。 – TonyK 2011-05-18 23:35:49
@TonyK:有一次,海湾合作委员会的一个编译器为此产生了警告。但是,它不是4.6.0,4.5.x或4.2.1 - 我手边的版本。我必须误解......虽然有一些公正的观察结果,用普通字符串使用'printf()'没有太多的意义。我会修复评论。 (正如你所说的,'printf(s)'引发的格式化字符串漏洞,其中's'是一个用户控制的字符串,这是一个更严重的问题。) – 2011-05-18 23:45:39