2011-05-18 124 views
1

由于暗示的标题,什么的意思,如果我做这在C++得到印刷:如果我使用printf(“one 0two”),会发生什么情况;?

​​

?当我这样做时,GCC给了我一个警告,但是visual studio对它很好。他们的工作方式有什么不同?考虑一下,我期望printf在第一个\ 0处停下来,但显然这个代码使用到现在一直在windows上工作正常,所以我不确定。

回答

8

您将获得:

$ 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 $ 
5

C样式的字符串以NULL结尾。所以当打印一个字符串时,它会打印所有内容,直到第一次出现空字符。在这种情况下,它应该打印one而没有别的。

4

你得到'一'打印 - 后面没有换行符。

您还收到编译器警告。

海湾合作委员会正在善待 - 让你知道'两'是无关紧要的。 您也不应该使用使用printf()的格式字符串中没有%标记是没有意义的...您可以使用puts()fputs()来代替。由于安全原因,不使用用户可以选择的格式字符串至关重要:char *s = ...; printf(s);

MSVS在没有给你警告的时候没有错;编译器没有义务建议修复代码的方法。

+2

“你也不应该使用printf()和一个没有%标记的格式字符串”:这对我来说是新的!为什么不是?我一直这样做。也许你的意思是你不应该使用'printf(s)'来打印任意字符串(可能包含%标记)?我同意这一点。 – TonyK 2011-05-18 23:35:49

+0

@TonyK:有一次,海湾合作委员会的一个编译器为此产生了警告。但是,它不是4.6.0,4.5.x或4.2.1 - 我手边的版本。我必须误解......虽然有一些公正的观察结果,用普通字符串使用'printf()'没有太多的意义。我会修复评论。 (正如你所说的,'printf(s)'引发的格式化字符串漏洞,其中's'是一个用户控制的字符串,这是一个更严重的问题。) – 2011-05-18 23:45:39

2

printf的确会停在嵌入的“空”字符处,而只是打印“一个”。

GCC发出警告,因为这样的格式字符串很可能是错误的;它还会将格式字符串与参数类型进行比较,如果不匹配则发出警告。其他编译器不会花费太多精力来分析诸如printf之类的函数的参数,并且会在没有任何警告的情况下让有缺陷的参数通过。

相关问题