在c語言中,我們如果希望進行格式化進行輸出,一般我們用 sprintf 來字串。
例如:char temp[100];
sprintf(temp, "%s", "helloworld" );
通常上面的操作應該沒有任何問題。但是,在某些情況下,是有意想不到的結果產生。
比如:在進行出錯資訊進行輸出時,我們採取如下寫法:
char temp[64];
sprintf( temp, "error at file %s , line %d , column %d , message: %s", strfile, linenumber, columnnumber, strmessage);
一般情況下,如果出錯資訊較少,上面程式沒有任何問題,如果出錯資訊很長,上面的資料會越界,從而導致改寫其他記憶體中的內容,引發一些你想象不到的錯誤。
這時,估計你的解決方案就是增大temp的空間,比如:temp[1000]。
沒錯,這樣改正之後,造成上面出錯的概率會較少很多,但是還沒有完全解決此問題。
在使用者如果提供比較多的出錯資訊時,還是有問題產生。
那麼我們有沒有辦法來完全解決此問題呢????
在c++中,有個string類,可以用來動態儲存字串,它會根據當前字串的長度來調整它的長度。
且string.begin() 相當於char*指標。
說到這,你是不是有一種衝動改寫上面的程式?( i so ).
string strtemp;
strtemp.reserve(64); //優化string的記憶體分配策略
sprintf( strtemp.begin(), "error at file %s , line %d , column %d , message: %s", strfile, linenumber, columnnumber, strmessage);
編譯通過,^_^(竊喜) !
測試一下,在較短的出錯訊息(沒有超過64)時,沒有任何問題,但是在超過64之後,會進行出錯!!!(是不是比上面的比較『安全』? )
為什麼上面會出錯???string 不是動態進行擴充套件儲存空間嗎?
沒錯,如果超過64之後,string會進行動態分配空間,由於string一般確保它的儲存空間連續性,所以它是重新分配一塊足夠大的空間,然後將資料copy過去,這個過程類似於realloc 來分配空間。這必然導致我們現在的string.begin()和以前的begin()所指向的位址不一樣。
而我們sprintf指向的位址是以前的string.begin(),不是重新分配之後的空間,一般以前分配的空間會被釋放,所以會導致程式出錯。
哪我們還有沒有別的辦法來改善上面的問題???
mfc中的cstring類有個成員函式format就可以用來格式化字串,並且可以動態擴充套件此字串。
是不是很酷???
但是,對於我來說,凡是不在ui地方(即介面顯示部分),盡量避免使用mfc中的內容,使得以後的移植比較方便(可能有點杞人憂天的感覺),嘿嘿!!
難道就沒有別的解決方案???
畢竟格式化字串是非常常見的事情,連c中都有乙個特定的函式來完成(sprintf)。難道c++裡面就沒有解決方案嗎?
記得在c++的io輸出流中,標準的cout,就可以用來格式化輸出到螢幕。
如果是fstream就可以用於格式化輸出到檔案中。(說到這裡,好像記得有個字串流?)
趕快進行msdn搜尋,呵呵,找到了這個傢伙。
不再多說了,直接進行示例.
std::ostringstream strout( ios_base::out);
strout << "error at file " << file
<< " line " << linenumber << " column " << columnnumber << endl;
strout << " message:" << cerrormsg(errorcode).geterrormsg() << endl;
strout << " usermessage: " << errstr << endl;
然後我們可以把上面的字串提取出來.
string strvalue = strout.str();
到了這一步,你應該知道如何來使用string型別的值了吧。
呵呵,終於將它進行解決了,並且解決的如此徹底( 噓,不要告訴別人,告訴你乙個秘密,以前碰到此問題,沒有很好的進行解決過,只是適當的將temp的陣列增大,即將出錯的概率進行了降低!)。
什麼??? 你無法編譯???? 加入相關標頭檔案不就可以了嗎???不知道哪個標頭檔案,那去msdn中查詢啊。
什麼你沒有查到?耐心一點會有的(不過在比較隱蔽的地方)。
use to work with objects of type basic_string.
use work with char *, which are c strings
即:在上面中,我們只要加入下面一句就可以了:
#include
字串格式化
sprintf snprintf snprintf std stringstream std strstream boost lexical cast boost format cstring format 1 sprintf 使用 sprintf 不安全,輕則破壞資料的準確性,重則程式崩潰。請看下...
格式化字串
通常在使用字串的時候,會對字串進行格式化,然後輸出或呼叫 一般我們使用替換標記對字串進行格式化 string str1 string.format add is 1,2,3 而且在c 中的替換標記可以以任意順序和次數出現在格式化字串中,但替換值是按順序排的,而且替換標記不能超出索引範圍 string...
字串格式化
例如 string s hello map.put target world string res format s,map 有什麼用呢?比如在some.properties中配置模板字串,但是如果用 這種方式,在配置了spring讀取properties注入變數的時候,這個變數就找不到會報錯。這個...