C++:sprintf()的用法

轉:http://blog.csdn.net/masikkk/article/details/5634886安全

更多:http://blog.csdn.net/zjuwispersure/article/details/6083982函數

在將各類類型的數據構形成字符串時,sprintf 的強大功能不多會讓你失望。因爲sprintf 跟printf 在用法上幾乎同樣,只是打印的目的地不一樣而已,前者打印到字符串中,後者則直接在命令行上輸出。這也致使sprintf 比printf 有用得多。
  sprintf 是個變參函數,定義以下:
  int sprintf( char *buffer, const char *format [, argument] ... );
  除了前兩個參數類型固定外,後面能夠接任意多個參數。而它的精華,顯然就在第二個參數:
編碼

  (1)格式化字符串上。spa

  printf 和sprintf 都使用格式化字符串來指定串的格式,在格式串內部使用一些以「%」開頭的格式說明符(format specifications)來佔據一個位置,在後邊的變參列表中提供相應的變量,最終函數就會用相應位置的變量來替代那個說明符,產生一個調用者想要的字符串。
  格式化數字字符串
  sprintf 最多見的應用之一莫過於把整數打印到字符串中,因此,spritnf 在大多數場合能夠替代itoa。
  如:
  //把整數123 打印成一個字符串保存在s 中。
  sprintf(s, "%d", 123); //產生"123"
  能夠指定寬度,不足的左邊補空格:
  sprintf(s, "%8d%8d", 123, 4567); //產生:" 123 4567"
  固然也能夠左對齊:
  sprintf(s, "%-8d%8d", 123, 4567); //產生:"123 4567"
  也能夠按照16 進制打印:
  sprintf(s, "%8x", 4567); //小寫16 進制,寬度佔8 個位置,右對齊
  sprintf(s, "%-8X", 4568); //大寫16 進制,寬度佔8 個位置,左對齊
  這樣,一個整數的16 進制字符串就很容易獲得,但咱們在打印16 進制內容時,一般想要一種左邊補0 的等寬格式,那該怎麼作呢?很簡單,在表示寬度的數字前面加個0 就能夠了。
  sprintf(s, "%08X", 4567); //產生:"000011D7"
  上面以」%d」進行的10 進制打印一樣也可使用這種左邊補0 的方式。
  這裏要注意一個符號擴展的問題:好比,假如咱們想打印短整數(short)-1 的內存16 進製表示形式,在Win32 平臺上,一個short 型佔2 個字節,因此咱們天然但願用4 個16 進制數字來打印它:
  short si = -1;
  sprintf(s, "%04X", si);
  產生「FFFFFFFF」,怎麼回事?由於spritnf 是個變參函數,除了前面兩個參數以外,後面的參數都不是類型安全的,函數更沒有辦法僅僅經過一個「%X」就能得知當初函數調用前參數壓棧時被壓進來的究竟是個4 字節的整數仍是個2 字節的短整數,因此採起了統一4 字節的處理方式,致使參數壓棧時作了符號擴展,擴展成了32 位的整數-1,打印時4 個位置不夠了,就把32 位整數-1 的8 位16 進制都打印出來了。
  若是你想看si 的原本面目,那麼就應該讓編譯器作0 擴展而不是符號擴展(擴展時二進制左邊補0 而不是補符號位):
  sprintf(s, "%04X", (unsigned short)si);
  就能夠了。或者:
  unsigned short si = -1;
  sprintf(s, "%04X", si);
  sprintf 和printf 還能夠按8 進制打印整數字符串,使用」%o」。注意8 進制和16 進制都不會打
  印出負數,都是無符號的,實際上也就是變量的內部編碼的直接的16 進制或8 進製表示。
  控制浮點數打印格式
  浮點數的打印和格式控制是sprintf 的又一大經常使用功能,浮點數使用格式符」%f」控制,默認保
  留小數點後6 位數字,好比:
  sprintf(s, "%f", 3.1415926); //產生"3.141593"
  但有時咱們但願本身控制打印的寬度和小數位數,這時就應該使用:」%m.nf」格式,其中m 表
  示打印的寬度,n 表示小數點後的位數。好比:
  sprintf(s, "%10.3f", 3.1415626); //產生:" 3.142"
  sprintf(s, "%-10.3f", 3.1415626); //產生:"3.142 "
  sprintf(s, "%.3f", 3.1415626); //不指定總寬度,產生:"3.142"
  注意一個問題,你猜
  int i = 100;
  sprintf(s, "%.2f", i);
  會打出什麼東東來?「100.00」?對嗎?本身試試就知道了,同時也試試下面這個:
  sprintf(s, "%.2f", (double)i);
  第一個打出來的確定不是正確結果,緣由跟前面提到的同樣,參數壓棧時調用者並不知道跟i相對應的格式控制符是個」%f」。而函數執行時函數自己則並不知道當年被壓入棧裏的是個整數,因而可憐的保存整數i 的那4 個字節就被不禁分說地強行做爲浮點數格式來解釋了,整個亂套了。不過,若是有人有興趣使用手工編碼一個浮點數,那麼倒可使用這種方法來檢驗一下你手工編排的結果是否正確。
.net

相關文章
相關標籤/搜索