2011-05-18 118 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之類的函數的參數,並且會在沒有任何警告的情況下讓有缺陷的參數通過。

相關問題