MFC學習之三 字串型別使用與轉換

2021-05-24 02:31:19 字數 4418 閱讀 1223

cstring 是一種很有用的資料型別,使用cstring可以讓你對字串的操作更加直截了當。

1、cstring 物件的連線

能體現出 cstring 型別方便性特點的乙個方面就字串的連線,使用 cstring 型別,你能很方便地連線兩個字串,正如下面的例子:

cstring gray("gray");

cstring cat("cat");

cstring graycat = gray + cat;

2、格式化字串

與其用 sprintf() 函式或 wsprintf() 函式來格式化乙個字串,還不如用 cstring 物件的format()方法:

cstring s;

s.format(_t("the total is %d"), total);

用這種方法的好處是你不用擔心用來存放格式化後資料的緩衝區是否足夠大,這些工作由cstring類替你完成。

格式化是一種把其它不是字串型別的資料轉化為cstring型別的最常用技巧,比如,把乙個整數轉化成cstring型別,可用如下方法:

cstring s;

s.format(_t("%d"), total);

#define _t(x) x // 非unicode版本(non-unicode version)
而在unicode環境下是如下定義的:

#define _t(x) l##x // unicode版本(unicode version)
所以在unicode環境下,它的效果就相當於:

s.format(l"%d", total);
如果你認為你的程式可能在unicode的環境下執行,那麼開始在意用 unicode 編碼。比如說,不要用 sizeof() 操作符來獲得字串的長度,因為在unicode環境下就會有2倍的誤差。我們可以用一些方法來隱藏unicode的一些細節,比如在我需要獲得字元長度的時候,我會用乙個叫做dim的巨集,這個巨集是在我的dim.h檔案中定義的,我會在我寫的所有程式中都包含這個檔案:

#define dim(x) ( sizeof((x)) / sizeof((x)[0]) )
這個巨集不僅可以用來解決unicode的字串長度的問題,也可以用在編譯時定義的**上,它可以獲得**的項數,如下:

class whatever ;

whatever data = ,

...,

};for(int i = 0; i < dim(data); i++) // 掃瞄**尋找匹配項。

tchar data[20];

lstrcpyn(data, longstring, sizeof(data) - 1); // wrong!

lstrcpyn(data, longstring, dim(data) - 1); // right

writefile(f, data, dim(data), &byteswritten, null); // wrong!

writefile(f, data, sizeof(data), &byteswritten, null); // right

造成以上原因是因為lstrcpyn需要乙個字元個數作為引數,但是writefile卻需要位元組數作為引數。

同樣需要注意的是有時候需要寫出資料的所有內容。如果你僅僅只想寫出資料的真實長度,你可能會認為你應該這樣做:

writefile(f, data, lstrlen(data), &byteswritten, null); // wrong
但是在unicode環境下,它不會正常工作。正確的做法應該是這樣:

writefile(f, data, lstrlen(data) * sizeof(tchar), &byteswritten, null); // right
因為writefile需要的是乙個以位元組為單位的長度。(可能有些人會想「在非unicode的環境下執行這行**,就意味著總是在做乙個多餘的乘1操作,這樣不會降低程式的效率嗎?」這種想法是多餘的,你必須要了解編譯器實際上做了什麼,沒有哪乙個c或c++編譯器會把這種無聊的乘1操作留在**中。在unicode環境下執行的時候,你也不必擔心那個乘2操作會降低程式的效率,記住,這只是乙個左移一位的操作而已,編譯器也很樂意為你做這種替換。)

使用_t巨集並不是意味著你已經建立了乙個unicode的程式,你只是建立了乙個有unicode意識的程式而已。如果你在預設的8-bit模式下編譯你的程式的話,得到的將是乙個普通的8-bit的應用程式(這裡的8-bit指的只是8位的字元編碼,並不是指8位的計算機系統);當你在unicode環境下編譯你的程式時,你才會得到乙個unicode的程式。記住,cstring 在 unicode 環境下,裡面包含的可都是16位的字元哦。

3、cstring 型轉化成 int 型

雖然通常你懷疑使用_atoi()函式是乙個好的選擇,它也很少會是乙個正確的選擇。如果你準備使用 unicode 字元,你應該用_ttoi(),它在 ansi 編碼系統中被編譯成_atoi(),而在 unicode 編碼系統中編譯成_wtoi()。你也可以考慮使用_tcstoul()或者_tcstol(),它們都能把字串轉化成任意進製的長整數(如二進位制、八進位制、十進位制或十六進製制),不同點在於前者轉化後的資料是無符號的(unsigned),而後者相反。看下面的例子:

cstring hex = _t("fab");

cstring decimal = _t("4011");

assert(_tcstoul(hex, 0, 16) == _ttoi(decimal));

4、cstring 型和 char* 型別的相互轉化

不要嘗試:cstring graycat = "gray" + "cat";

你可以象下面這樣做:cstring graycat = cstring("gray") + cstring("cat");
或者這樣:

cstring graycat = cstring("gray") + "cat";
研究一番就會發現:「 +」總是使用在至少有乙個 cstring 物件和乙個 lpcstr 的場合。

注意,編寫有 unicode 意識的**總是一件好事,比如:

cstring graycat = cstring(_t("gray")) + _t("cat");
這將使得你的**可以直接移植。

cstring 轉化成 char* 之一強制型別轉換為 lpctstr;

cstring轉化成char* 之二使用 cstring 物件的 getbuffer 方法

5、cstring 型轉化成 bstr 型

當我們使用 activex 控制項程式設計時,經常需要用到將某個值表示成 bstr 型別。bstr 是一種記數字串,intel平台上的寬字串(unicode),並且 可以包含嵌入的 null 字元。

你可以呼叫 cstring 物件的 allocsysstring 方法將 cstring 轉化成 bstr:

6、bstr 型轉化成 cstring 型

由於 bstr 是記數 unicode 字串,你可以用標準轉換方法來建立 8 位的 cstring。實際上,這是 cstring 內建的功能。在 cstring 中 有特殊的建構函式可以把 ansi 轉化成 unicode,也可以把unicode 轉化成 ansi。你同樣可以從 variant 型別的變數中獲得 bstr 型別的字串,variant 型別是 由各種 com 和 automation (自動化)呼叫返回的型別。

例如,在乙個ansi程式中:

bstr b;

b = ...; // whatever

cstring s(b == null ? l"" : b)

7、cstring 型轉const char*
在多位元組環境下,cstring可以直接轉換成const char *,但在unicode環境下,會出現cosnt char 不能轉換成lpctstr的錯誤,可以使用如下方法轉換:
cstring str("test");

char st[5];

int ilenth;

ilenth = widechartomultibyte(cp_acp,0,str,-1,null,0,null,0);

widechartomultibyte(cp_acp,0,str,-1, st,ilenth,null,null);

更多可參考:http://www.vckbase.com/document/viewdoc/?id=1094

三 字串 一

三 字串 1。直接量三種寫法 1 單引號,不會替換變數,且只支援 兩個轉譯字元 2 雙引號,會進行變數替換,雙引號能支援除了 以外的所有轉譯符 3 heredoc,比如 string end of string haha hehe hoho.hehe end of string 其中end of s...

三 字串操作

windows核心編碼字符集採用unicode字符集,字串處理使用unicode string,是乙個結構體,定義如下 typedef struct unicode string unicode string length 字串長度,maximumlength 字串緩衝區長度,buffer 字串緩衝...

三 字串補充

1 輸出函式中的字串的格式化 之前有簡單地使用了說明了prin函式中字串的拼接。name xiong age 21 男 high 175weight 56 print 我姓 s,性別 s,今年 s歲,身高 scm,體重 skg。name,age,high,weight 為了保證絕對正確。只需要將上面...