1、sprintf
字符串格式化命令,主要功能是把格式化的數據寫入某個字符串中。sprintf 是個變參函數。
原型
int sprintf( char *buffer, const char *format, [ argument] … );
參數列表
buffer:
char型指針,指向將要寫入的字符串的緩衝區。
format:格式化字符串。
[argument]...:可選參數,可以是任何類型的數據。
1
2
3
4
5
6
7
8
9
10
11
|
#include<stdio.h>//某個頭文件
intmain()
{
charbuffer[50];
intn,a=5,b=3;
n= sprintf (buffer, "%dplus%dis%d" ,a,b,a+b);
printf ( "[%s]isastring%dcharslong\n" ,buffer,n);
return0;
}
|
輸出結果:
[5 plus 3 is 8] is a string 13 chars long
|
sprintf格式的規格如下所示。[]中的部分是可選的。
若想輸出'%'本身時, 請使用'%%'處理。
1. 處理字符方向。負號時表示從後向前處理。
2. 填空字元。 0 的話表示空格填 0;空格是內定值,表示空格就放着。
4. 精確度。指在小數點後的浮點數位數。
%% 印出百分比符號,不轉換。
%c 整數轉成對應的 ASCII 字元。
%d 整數轉成十進位。
%f 倍精確度數字轉成浮點數。
%o 整數轉成八進位。
%s 整數轉成字符串。
%x 整數轉成小寫十六進位。
%X 整數轉成大寫十六進位。
$money = 123.1
$formatted = sprintf ("%06.2f", $money); // 此時變數 $ formatted 值爲 "123.10"
$formatted = sprintf ("%08.2f", $money); // 此時變數 $ formatted 值爲 "00123.10"
$formatted = sprintf ("%-08.2f", $money); // 此時變數 $ formatted 值爲 "123.1000"
$formatted = sprintf ("%.2f%%", 0.95 * 100); // 格式化爲百分比
舉例子:
1、sprintf(s, "%d", 123);
//產生"123"
//把整數123 打印成一個字符串保存在s 中。所以,sprintf 在大多數場合可以替代
itoa。
2、sprintf(s, "%4d%4d",
123, 4567);
//產生:" 1234567"可以指定寬度,不足的左邊補空格:
3、sprintf(s, "%-4d%4d",
123, 4567);
//產生:"123 4567"
4、sprintf(s,
"%f", 3.1415926);
//產生"3.141593"
%f,默認保留小數點後6 位數字
5、
char a1[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
char a2[] = {'H', 'I', 'J', 'K', 'L', 'M', 'N'};
如果:
sprintf(s, "%s%s", a1, a2); //Don't do that!
十有八九要出問題了。是否可以改成:
sprintf(s, "%7s%7s", a1, a2);
也沒好到哪兒去,正確的應該是:
sprintf(s, "%.7s%.7s", a1, a2);//產生:"ABCDEFGHIJKLMN"
這可以類比打印浮點數的”%m/nf”,在”%m.ns”中,m 表示佔用寬度(
字符串長度不足時補空格,超出了則按照實際寬度打印),n 才表示從相應的字符串中最多取用的字符數。通常在打印字符串時m 沒什麼大用,還是點號後面的n 用的多。自然,也可以前後都只取部分
字符:
sprintf(s, "%.6s%.5s", a1, a2);//產生:"ABCDEFHIJKL"
在許多時候,我們或許還希望這些格式控制符中用以指定長度信息的數字是動態的,而不是靜態指定的,因爲許多時候,程序要到運行時纔會清楚到底需要取
字符數組中的幾個字符,這種動態的寬度/精度設置功能在sprintf
的實現中也被考慮到了,sprintf 採用”*”來佔用一個本來需要一個指定寬度或精度的常數數字的位置,同樣,而實際的寬度或精度就可以和其它被打印的
變量一樣被提供出來,於是,上面的例子可以變成:
sprintf(s, "%.*s%.*s", 7, a1, 7, a2);
或者:
sprintf(s, "%.*s%.*s", sizeof(a1), a1, sizeof(a2), a2);
實際上,前面介紹的打印
字符、整數、浮點數等都可以動態指定那些
常量值,比如:
1
2
3
|
sprintf (s, "%-*d" ,4, 'A' );
sprintf (s, "%#0*X" ,8,128);
sprintf (s, "%*.*f" ,10,2,3.1415926);
|
6、打印地址信息
打印地址信息
有時
調試程序時,我們可能想查看某些
變量或者成員的地址,由於地址或者
指針也不過是個32
位的數,你完全可以使用打印
無符號整數的”%u”把他們打印出來:
不過通常人們還是喜歡使用16 進制而不是10 進制來顯示一個地址:
然而,這些都是間接的方法,對於地址打印,sprintf 提供了專門的”%p”:
我覺得它實際上就相當於:
1
|
sprintf (s, "%0*x" ,2* sizeof ( void *),&i);
最後:
|
sprintf_s和snprintf
sprintf_s()是sprintf()的安全版本,通過指定
緩衝區長度來避免sprintf()存在的溢出風險
。在使用VS2008時如果你使用了sprintf函數,那麼
編譯器會發出警告:使用sprintf存在風險,建議使用
sprintf_s。這個安全版本的原型是:
int sprintf_s(char *buffer,size_t sizeOfBuffer,const char *format [,argument] ... );
不過sprintf_s()是微軟私有的函數,考慮到跨平臺移植,最好使用snprintf()。兩者的原型基本相同:
int _snprintf(char *buffer, size_t count, const char *format [,argument] ... );