簡體   English   中英

sprintf()是否需要格式說明符才能正常工作?

[英]Does sprintf() require format specifiers to work properly?

我已閱讀sprintf格式說明符 post by none以及其他相關內容,但還沒有看到專門解決的問題。

直到今天,我還從未見過sprintf僅用於兩個參數。
我的系統用於sprintf()的原型是:

int sprintf (char Target_String[], const char Format_String[], ...);

在處理一些舊代碼時,我遇到了這個問題:(為簡化說明)

char toStr[30];
char fromStr[]={"this is the in string"};
sprintf(toStr, fromStr);

我的原型的解釋是,第二個參數應當由的const char[]並接受標准ANSI C格式說明這些

但是上面的示例似乎可以很好地使用字符串fromStr作為第二個參數。
這純粹是通過未定義的行為起作用嗎?還是這種用法完全合法?

我使用C99編譯器在Windows 7上工作。

完全合法。 可變參數是可選的。

在這種情況下,printf用作strcpy,但為%說明符解析fmt字符串。

我會寫sprintf(toStr,"%s",fromStr); 因此它不必解析該長字符串。

您觀察到的行為是正確的,不需要任何轉換說明符的格式字符串。 在這種情況下,由...表示的變長參數列表的長度為零。 這是完全合法的,盡管它的效率絕對不如同等效率

strcpy(toStr, fromStr);

這是完全合法的代碼,但是

  1. 如果只想復制字符串,請改用strcpy()
  2. 如果使用用戶輸入,則可能使自己容易受到格式字符串攻擊

sprintf簡介是:

int sprintf(char *str, const char *format, ...);

這意味着有兩個參數是合法的選擇。

之所以有效,是因為您沒有其他要打印的參數(即沒有控制格式% )。

與沒有第二個參數的printf沒什么區別:

int printf ( const char * format, ... );

如果您沒有第二個參數,它也可以工作:

printf(fromStr);

第二個參數應包含const char[]

函數參數的const說明符保證函數不會更改該參數的值(假設可以更改該參數的值,這是數組的情況,因為它們是通過地址傳遞給函數的)。 它不要求在實際調用中使用const值。

您發布的代碼不使用const字符串作為sprintf()的第二個參數,但是從非const到const的轉換是隱式的; 那里不必擔心。

接受標准的ansi C格式說明符

“接受”並不意味着“要求”。 您指定的格式字符串不包含任何格式說明符。 因此,僅使用2個參數調用該函數(沒有要格式化的值)。 無論如何,第三個參數將被sprinf()忽略,許多現代編譯器都會對此發出警告。


更新 :我不想就哪些編譯器是現代的而哪些不是現代的展開辯論。

碰巧我在OSX 10.11上使用了默認的編譯器,它的輸出是:

axiac: ~/test$ cc -v
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.3.0
Thread model: posix
axiac: ~/test$ cc -o 1 1.c
1.c:8:25: warning: data argument not used by format string [-Wformat-extra-args]
    sprintf(x, "abc\n", n);
               ~~~~~~~  ^

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM