C++中sprintf()函式的使用詳解
轉載文章:http://www.jb51.net/article/36937.htm
參考文章:sprintf用法 http://blog.sina.com.cn/s/blog_980cf62a0100ya0z.html
在將各種型別的資料構造成字串時,sprintf 的強大功能很少會讓你失望。由於sprintf 跟printf 在用法上幾乎一樣,只是列印的目的地不同而已,前者列印到字串中,後者則直接在命令列上輸出。這也導致sprintf 比printf 有用得多。
函式簡介
函式功能:把格式化的資料寫入某個字串 函式原型:int sprintf( char *buffer, const char *format [, argument] … );引數說明及應用舉例
sprintf格式的規格如下所示。[]中的部分是可選的。 %[指定引數][識別符號][寬度][.精度]指示符 若想輸出`%'本身時, 請這樣`%%'處理。 1. 處理字元方向。負號時表示從後向前處理。 2. 填空字元。 0 的話表示空格填 0;空格是內定值,表示空格就放著。 3. 字元總寬度。為最小寬度。 4. 精確度。指在小數點後的浮點數位數。 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-轉換字元
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- %% 印出百分比符號,不轉換。使用sprintf 的常見問題
sprintf 是個變參函式,使用時經常出問題,而且只要出問題通常就是能導致程式崩潰的記憶體訪 問錯誤,但好在由sprintf 誤用導致的問題雖然嚴重,卻很容易找出,無非就是那麼幾種情況,通 常用眼睛再把出錯的程式碼多看幾眼就看出來了。 sprintf_s()是sprintf()的安全版本,通過指定緩衝區長度來避免sprintf()存在的溢位風險 。在使用VS2008時如果你使用了sprintf函式,那麼編譯器會發出警告:使用sprintf存在風險,建議使用sprintf_s。這個安全版本的原型是:sprintf 是個變參函式,定義如下:
int sprintf( char *buffer, const char *format [, argument] ... );
除了前兩個引數型別固定外,後面可以接任意多個引數。而它的精華,顯然就在第二個引數:
(1)格式化字串上。
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 個位元組就被不由分說地強行作為浮點數格式來解釋了,整個亂套了。不過,如果有人有興趣使用手工編碼一個浮點數,那麼倒可以使用這種方法來檢驗一下你手工編排的結果是否正確。
相關推薦
C++中建構函式詳解
c++類的建構函式詳解 一、 建構函式是幹什麼的 class Counter { public: // 類Counter的建構函式 // 特點:
C++ 中malloc函式詳解(轉載)
一、原型:extern void *malloc(unsigned int num_bytes); 標頭檔案:#include <malloc.h> 或 #include <alloc.h> (注意:alloc.h 與 malloc.h
C++中sprintf()函式的使用詳解
轉載文章:http://www.jb51.net/article/36937.htm 參考文章:sprintf用法 http://blog.sina.com.cn/s/blog_980cf62a0100ya0z.html 在將各種型別的資料構造成字串時,sprintf 的
整理:C++中sprintf()函式的使用詳解
sprintf 是個變參函式,定義如下:int sprintf( char *buffer, const char *format [, argument] ... ); 除了前兩個引數型別固定外,後面可以接任意多個引數。而它的精華,顯然就在第二個引數:(1)格式化字串上。printf 和sprintf 都使
C/C++中extern關鍵字詳解
編譯器 fin 生成 接口 bcd 只需要 c++環境 結束 編程 轉自:http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html 1 基本解釋:extern可以置於變量或者函數前,以標示變量或者
C/C++中作用域詳解(轉)
防止 局部作用域 gist 文件中 方式 為什麽不使用 形式參數 lan archive 作用域規則告訴我們一個變量的有效範圍,它在哪兒創建,在哪兒銷毀(也就是說超出了作用域)。變量的有效作用域從它的定義點開始,到和定義變量之前最鄰近的開括號配對的第一個閉括號。也就是說,作
C#中const用法詳解
htm 鏈接 服務器 span img body 用法詳解 -s 設計 本文實例講述了C#中const用法。分享給大家供大家參考。具體用法分析如下: const是一個c語言的關鍵字,它限定一個變量不允許被改變。使用const在一定程度上可以提高程序的安全性和可靠性,另外,
C#中protected用法詳解
base 而是 報錯 public 我們 此刻 訪問 .html 定義 轉自(https://www.cnblogs.com/wangyt223/archive/2012/08/08/2627801.html) 在c#的可訪問性級別中,public和private算是最
c/c++中static的詳解
extern info system pan 特點 靜態成員 額外 定義 全局 C 語言的 static 關鍵字有三種(具體來說是兩種)用途: 1. 靜態局部變量:用於函數體內部修飾變量,這種變量的生存期長於該函數。 int foo(){ st
C#中ToString()格式詳解
padding design otn href 有效 詳解 pattern console AS 以下內容均摘自博客園,僅供資料查詢。原文連接http://www.cnblogs.com/xdotnet/archive/2009/01/17/tostring_format.
C++中的繼承詳解
C++ 繼承 [TOC] 繼承基本知識 定義: 繼承是面向對復用的重要手段。通過繼承定義一個類,繼承是類型之間的關系建模,共享公有的東西,實現各自本質不同的東西。 繼承關系: 三種繼承關系下基類成員的在派生類的訪問關系變化(圖) 舉個栗子(公有繼承) ```c+
C++中列舉enum詳解
轉載部落格地址:https://blog.csdn.net/bruce_0712/article/details/54984371 眾所周知,C/C++語言可以使用#define和const建立符號常量,而使用enum工具不僅能夠建立符號常量,還能定義新
C/C++中volatile關鍵字詳解
asm 運行 多線程並發 這樣的 修改 由於 設定 其他 硬件 1. 為什麽用volatile? C/C++ 中的 volatile 關鍵字和 const 對應,用來修飾變量,通常用於建立語言級別的 memory barrier。這是 BS 在 "The C++ P
《隨筆十七》—— C++中的 “ 指標詳解 ”
目錄 指標的概念 指標所指向的型別 指標的值 指標本身所佔據的記憶體區 指標的算術運算 運算子&和* 指標表示式 陣列和指標的關係 指標和結構型別的關係 指標和函式的關係
C++中的string詳解
標準庫型別string表示可變長的字元序列,為了在程式中使用string型別,我們必須包含標頭檔案: #include <string> 宣告一個字串 宣告一個字串有很多種方式,具體如下: 1 string s;//呼叫預設建構函式,s為一個空
C++中string類詳解(轉載)(最下面有程式碼實現)
作者:yzl_rex 來源:CSDN 原文:https://blog.csdn.net/yzl_rex/article/details/7839379 要想使用標準C++中string類,必須要包含 #include < string>// 注意是< string>
linux中fork() 函式詳解
fork入門知識 一個程序,包括程式碼、資料和分配給程序的資源。fork()函式通過系統呼叫建立一個與原來程序幾乎完全相同的程序,也就是兩個程序可以做完全相同的事,但如果初始引數或者傳入的變數不同,兩個程序也可以做不同的事。 一個程序呼叫fork()函式後,系統先給新的程序分配資源,例如儲存資料和程式碼的
C++中const關鍵字詳解
const關鍵字作用 1. 修飾變數 用法:const 型別說明符 變數名。 含義:說明該變數不可以被改變。 用途:常量命名等 2. 修飾
MATLAB中accumarray函式詳解
原文連結:https://blog.csdn.net/liuhuicsu/article/details/70739459?utm_source=blogxgwz0 先看看subs和val的具體內容 subs = [1 1 1; 2 1 2; 2 3 2; 2 1 2; 2
基於C++的circshift 函式詳解
函式講解 circshift函式是matlab中表示迴圈移位的函式,呼叫形式如下:B= circshift(A,K,m); 輸入引數解釋如下: A表示待移位的向量或矩陣; K表示所移位數,可以是數字,也可以是二維陣列,若是數字則可以和m協同作用來決定是行移