2 回答

TA貢獻(xiàn)1805條經(jīng)驗(yàn) 獲得超10個(gè)贊
sprintf的作用是將一個(gè)格式化的字符串輸出到一個(gè)目的字符串中,而printf是將一個(gè)格式化的字符串輸出到屏幕。
sprintf的第一個(gè)參數(shù)是目的字符串,如果不指定這個(gè)參數(shù),執(zhí)行過(guò)程中出現(xiàn) "該程序產(chǎn)生非法操作,即將被關(guān)閉...."的提示。
因?yàn)镃語(yǔ)言在進(jìn)行字符串操作時(shí)不檢查字符串的空間是否夠大,所以可能會(huì)出現(xiàn)數(shù)組越界而導(dǎo)致程序崩潰的問(wèn)題。
即使碰巧,程序沒(méi)有出錯(cuò),也不要這么用,因?yàn)樵缤頃?huì)出錯(cuò)。所以一定要在調(diào)用sprintf之前分配足夠大的空間給buf。
sprintf 是個(gè)變參函數(shù),定義如下:
int sprintf( char *buffer, const char *format [, argument] ... );
除了前兩個(gè)參數(shù)類型固定外,后面可以接任意多個(gè)參數(shù)。而它的精華,顯然就在第二個(gè)參數(shù):格式化字符串上。
printf 和sprintf 都使用格式化字符串來(lái)指定串的格式,在格式串內(nèi)部使用一些以“%”開頭的格式說(shuō)明符(format specifications)來(lái)占據(jù)一個(gè)位置,在后邊的變參列表中提供相應(yīng)的變量,最終
函數(shù)就會(huì)用相應(yīng)位置的變量來(lái)替代那個(gè)說(shuō)明符,產(chǎn)生一個(gè)調(diào)用者想要的字符串:
格式化數(shù)字字符串
sprintf 最常見的應(yīng)用之一是把整數(shù)打印到字符串中,所以,spritnf 在大多數(shù)場(chǎng)合可以替代itoa。如:
1>把整數(shù)123 打印成一個(gè)字符串保存在s 中。
sprintf(s, "%d", 123); //產(chǎn)生"123"
2>可以指定寬度,不足的左邊補(bǔ)空格:
sprintf(s, "%8d%8d", 123, 4567); //產(chǎn)生:" 123 4567"
3>當(dāng)然也可以左對(duì)齊:
sprintf(s, "%-8d%8d", 123, 4567); //產(chǎn)生:"123 4567"
4>也可以按照16 進(jìn)制打?。?/p>
sprintf(s, "%8x", 4567); //小寫16 進(jìn)制,寬度占8 個(gè)位置,右對(duì)齊
sprintf(s, "%-8X", 4568); //大寫16 進(jìn)制,寬度占8 個(gè)位置,左對(duì)齊
這樣,一個(gè)整數(shù)的16 進(jìn)制字符串就很容易得到,但我們?cè)诖蛴?6 進(jìn)制內(nèi)容時(shí),通常想要一種左邊補(bǔ)0 的等寬格式,那該怎么做呢?很簡(jiǎn)單,在表示寬度的數(shù)字前面加個(gè)0 就可以了。
sprintf(s, "%08X", 4567); //產(chǎn)生:"000011D7"
使用sprintf 的常見問(wèn)題
sprintf 是個(gè)變參函數(shù),使用時(shí)經(jīng)常出問(wèn)題,而且只要出問(wèn)題通常就是能導(dǎo)致程序崩潰的內(nèi)存訪問(wèn)錯(cuò)誤,但好在由sprintf 誤用導(dǎo)致的問(wèn)題雖然嚴(yán)重,卻很容易找出,無(wú)非就是那么幾種情況,通常用眼睛再把出錯(cuò)的代碼多看幾眼就看出來(lái)了。
1>>緩沖區(qū)溢出
第一個(gè)參數(shù)的長(zhǎng)度太短了,沒(méi)的說(shuō),給個(gè)大點(diǎn)的地方吧。當(dāng)然也可能是后面的參數(shù)的問(wèn)題,建議變參對(duì)應(yīng)一定要細(xì)心,而打印字符串時(shí),盡量使用”%.ns”的形式指定最大字符數(shù)。
2>>忘記了第一個(gè)參數(shù)
低級(jí)得不能再低級(jí)問(wèn)題,用printf 用得太慣了。
3>>變參對(duì)應(yīng)出問(wèn)題
通常是忘記了提供對(duì)應(yīng)某個(gè)格式符的變參,導(dǎo)致以后的參數(shù)統(tǒng)統(tǒng)錯(cuò)位,檢查檢查吧。尤其是對(duì)應(yīng)”*”的那些參數(shù),都提供了嗎?不要把一個(gè)整數(shù)對(duì)應(yīng)一個(gè)”%s”。

TA貢獻(xiàn)1818條經(jīng)驗(yàn) 獲得超3個(gè)贊
sprintf函數(shù)的格式:int sprintf( char *buffer, const char *format [, argument,...] );
除了前兩個(gè)參數(shù)固定外,可選參數(shù)可以是任意個(gè)。buffer是字符數(shù)組名;format是格式化字符串
常用方式
sprintf函數(shù)的功能與printf函數(shù)的功能基本一樣,只是它把結(jié)果輸出到指定的字符串中了,看個(gè)例子就明白了:
例:將”test 1 2”寫入數(shù)組s中
#include<stdio.h>int main(int argc, char *avgv[])
{
char s[40]; sprintf(s,"%s%d%c","test",1,'2'); /*第一個(gè)參數(shù)就是指向要寫入的那個(gè)字符串的指針,剩下的就和printf()一樣了
你可以比較一下,這是向屏幕輸入*/
printf("%s%d%c","test",1,'2'); return 0;
}12345678910
編譯:
g++ sprinftest.cpp -o sprinftest && ./sprinftest
輸出結(jié)果:
sprintftest12
sprintftest12
2.若”%s”等輸出符在字符串中
例:補(bǔ)全字符串str的缺省內(nèi)容
#include <iostream>#include <stdio.h>#include <cstring>int main(int argc, char *avgv[])
{ char str[] = "hel%co wo%sd! sp%stf test%d"; char buf[strlen(str)]; sprintf(buf, str, 'l', "rl", "rin", 1); std::cout << "str = "<< buf << "\nlen = " << strlen(buf) << std::endl; return 0;
}123456789101112
編譯:
g++ sprinftest.cpp -o sprinftest && ./sprinftest
輸出結(jié)果:
str = hello world! sprintf test1
len = 27
這種形式也可以將多個(gè)字符值或字符串值賦值到字符串str中,有多少個(gè)輸出符就后面就加多少個(gè)參數(shù)。
添加回答
舉報(bào)