C++中的字符串類型


  本人c++新手,最近用C++,發現c++里面需要處理的字符串類型讓我頭疼,通過查閱資料,總結在此,供日后查閱,也請前輩不吝賜教,指出不足。  

1.字符(串)表示分類

  C++提供了兩種字符串的表示形式,即C風格的字符串和標准字符串。 C++引入的是string 類類型,但實際上在許多程序的情形中我們有必要理解和使用老式的C 風格字符串。總共包括以下幾種類型:

  a.char 

  b.wchar_t

  c.TCHAR

  c.LPSTR

  d.LPCSTR

  e.LPTSTR

  f.LPCTSTR

  g.Cstring

  h.string

  i.BSTR

  

2.C風格字符串

  C 風格的字符串起源於C 語言並在C++中繼續得到支持,實際上在標准C++之前除了第三方字符串庫類之外它是惟一一種被支持的字符串。字符串被存儲在一個字符數組中,一般通過一個char*類型的指針來操縱它,標准C 庫為操縱C 風格的字符串提供了一組函數例如:
// 返回字符串的長度
int strlen( const char* );
// 比較兩個字符串是否相等
int strcmp( const char*, const char* );
// 把第二個字符串拷貝到第一個字符串中
char* strcpy(char*, const char* );
標准C 庫作為標准的C++的一部分被包含在其中為使用這些函數我們必須包含相關的C 頭文件
#include <cstring>
指向C 風格字符串的字符指針總是指向一個相關聯的字符數組,即使當我們寫一個字符串常量時,如:
const char *st = "The expense of spirit\n";
系統在內部也把字符串常量存儲在一個字符串數組中,然后st 指向該數組的第一個元素。
那么我們怎樣以字符串的形式來操縱st 呢?
一般地我們用指針的算術運算來遍歷C 風格的字符串,每次指針增加1 直到到達終止空字符為止例如:
while ( *st++ ) { ... }
char*類型的指針被解除引用並且測試指向的字符是true 還是false 。true 值是除了空字符外的任意字符(空字符在判斷語句中被莫認為是假),++是增加運算符它使指針指向數組中的下一個字符。
一般來說當我們使用一個指針時在解除指針的引用之前測試它是否指向某個對象是必要的,否則程序很可能會失敗例如:
int
string_length( const char *st )
{
int cnt = 0;
if ( st )
while ( *st++ )
++cnt; return cnt;
}

 

3、C++字符串類型
要使用string 類型必須先包含相關的頭文件
#include <string>

例如下面是上一小節定義的字符數組
#include <string>
string st( "The expense of spiritn" );

st 的長度由size()操作返回不包含終止空字符
cout << "The size of "<< st<< " is " << st.size()<< " characters, including the newlinen";
string 構造函數的第二種形式定義了一個空字符串,例如
string st2; // 空字符串
我們怎樣能保證它是空的當然一種辦法是測試size()是否為0
if ( ! st.size() )
// ok:

更直接的辦法是使用empty()操作
if ( st.empty() )
// ok: 空
如果字符串中不含有字符則empty()返回布爾常量true ,否則返回false
第三種形式的構造函數用一個string 對象來初始化另一個string 對象,例如
string st3( st );
將st3 初始化成st 的一個拷貝,怎樣驗證呢?等於操作符比較兩個string 對象,如果相等則返回true
if ( st == st3 )
// 初始化成功
怎樣拷貝一個字符串呢?最簡單的辦法是使用賦值操作符,例如
st2 = st3; // 把st3 拷貝到st2 中
首先將與st2 相關聯的字符存儲區釋放掉,然后再分配足夠存儲與st3 相關聯的字符的存儲區。最后將與st3 相關聯的字符拷貝到該存儲區中。
我們可以使用加操作符+ 或看起來有點怪異的復合賦值操作符+= 。將兩個或多
個字符串連接起來。例如:給出兩個字符串
string s1( "hello, " );
string s2( "worldn" );
我們可以按如下方式將兩個字符串連接起來,形成第三個字符串
string s3 = s1 + s2;
如果希望直接將s2 附加在s1 后面那么可使用+= 操作符
s1 += s2;
s1 和s2 的初始化包含了一個空格一個逗號以及一個換行,這多少有些不方便,它們的存在限制了對這些string 對象的重用,盡管它滿足了眼前的需要。一種替代做法就是混合
使用C 風格的字符串與string 對象。如下所示:
const char *pc = ", ";
string s1( "hello" );
string s2( "world" );
string s3 = s1 + pc + s2 + "n";

這種連接策略比較受歡迎,因為它使s1 和s2 處於一種更容易被重用的形式。這種方法
能夠生效是由於string 類型能夠自動將C 風格的字符串轉換成string 對象。例如:這使我們可以將一個C 風格的字符串賦給一個string 對象。
string s1;
const char *pc = "a character array";
s1 = pc; // ok
但是反向的轉換不能自動執行,對隱式地將string 對象轉換成C 風格的字符串。string
類型沒有提供支持,例如,
下面試圖用s1 初始化str。 就會在編譯時刻失敗
char *str = s1; // 編譯時刻類型錯誤
為實現這種轉換必須顯式地調用名為c_str()的操作
char *str = s1.c_str(); // 幾乎是正確的但是還差一點
名字c_str()代表了string 類型與C 風格字符串兩種表示法之間的關系。字面意思是給
我一個C 風格的字符串,表示——即指向字符數組起始處的字符指針。
但是這個初始化還是失敗了,這次是由於另外一個不同的原因,為了防止字符數組被
程序直接處理,c_str()返回了一個指向常量數組的指針
(下一節將解釋常量修飾符const)
const char*
str 被定義為非常量指針所以這個賦值被標記為類型違例,正確的初始化如下
const char *str = s1.c_str(); // ok
string 類型支持通過下標操作符訪問單個字符,例如在下面的代碼段中,字符串中的
所有句號被下划線代替
string str( "fa.disney.com" );
int size = str.size();
for ( int ix = 0; ix < size; ++ix )
if ( str[ ix ] == '.' )
str[ ix ] = '_';

4. 基本類型轉換

4.1.區別wchar_t,char,WCHAR

   ANSI:即 char,可用字符串處理函數:strcat( ),strcpy( ), strlen( )等以str打頭的函數。
   UNICODE:wchar_t是Unicode字符的數據類型,它實際定義在里:
   typedef unsigned short wchar_t;
   另外,在頭文件中有這樣的定義:typedef wchar_t WCHAR; 所以WCHAR實際就是wchar_t
   wchar_t 可用字符串處理函數:wcscat(),wcscpy(),wcslen()等以wcs打頭的函數。為了讓編譯器識別Unicode字符串,必須以在前面加一個“L”,例如: wchar_t *szTest=L"This is a Unicode string.";

4.2.TCHAR

在C語言里面提供了 _UNICODE宏(有下划線),在Windows里面提供了UNICODE宏(無下划線),只要定了_UNICODE宏和UNICODE宏,系統就會自 動切換到UNICODE版本,否則,系統按照ANSI的方式進行編譯和運行。只定義了宏並不能實現自動的轉換,他還需要一系列的字符定義支持。
1. TCHAR
如果定義了UNICODE宏則TCHAR被定義為wchar_t。
typedef wchar_t TCHAR;
   否則TCHAR被定義為char typedef char TCHAR;
2. LPTSTR
   如果定義了UNICODE宏則LPTSTR被定義為LPWSTR。
   typedef LPTSTR LPWSTR;
   否則TCHAR被定義為char typedef LPTSTR LPSTR;
   說明:在使用字符串常量的時候需要使用_TEXT(“MyStr”)或者_T("")來支持系統的自動轉換。

4.3.BSTR

   BSTR是一個帶長度前綴的字符串,主要由操作系統來管理的,所以要用api.主要用來和VB打交道的(VB里的string就是指它)要操作它的API函數有很多.比如SysAllocString,SysFreeString等等.
   vc里封裝它的類如_bstr_t,及ATL中的CComBSTR等.
   一個 BSTR 由頭部和字符串組成,頭部包含了字符串的長度信息,字符串中可以包含嵌入的 null 值。
   BSTR 是以指針的形式進行傳遞的。(指針是一個變量,包含另外一個變量的內存地址,而不是數據。) BSTR 是 Unicode 的,即每個字符需要兩個字節。 BSTR 通常以兩字節的 null 字符結束。 wstr是寬字符,以雙字節表示一個字符 bstr是為了與原先的basic字符兼容,它的最前面的4個字節為其長度,以'\0'結束.

4.4.更進一步的字符串以及其指針的類型定義 

由於Win32 API文檔的函數列表使用函數的常用名字(例如, "SetWindowText"),所有的字符串都是用TCHAR來定義的。(除了XP中引入的只適用於Unicode的API)。下面列出一些常用的typedefs,你可以在msdn中看到他們。

type Meaning in MBCS builds Meaning in Unicode builds
WCHAR wchar_t wchar_t
LPSTR char* char*
LPCSTR const char* const char*
LPWSTR wchar_t* wchar_t*
LPCWSTR wchar_t* wchar_t*
TCHAR TCHAR char wchar_t
LPTSTR TCHAR* TCHAR*
LPCTSTR const TCHAR* const TCHAR*


4.5.相互轉換

(1) char*轉換成CString
  若將char*轉換成CString,除了直接賦值外,還可使用CString::Format進行。例如:
char chArray[] = "This is a test";
char * p = "This is a test";
  或
LPSTR p = "This is a test";
  或在已定義Unicode應的用程序中
TCHAR * p = _T("This is a test");
  或
LPTSTR p = _T("This is a test");
CString theString = chArray;
theString.Format(_T("%s"), chArray);
theString = p;
  (2) CString轉換成char*
  若將CString類轉換成char*(LPSTR)類型,常常使用下列三種方法:
  方法一,使用強制轉換。例如:
CString theString( "This is a test" );
LPTSTR lpsz =(LPTSTR)(LPCTSTR)theString;
  方法二,使用strcpy。例如:
CString theString( "This is a test" );
LPTSTR lpsz = new TCHAR[theString.GetLength()+1];
_tcscpy(lpsz, theString);
  需要說明的是,strcpy(或可移值Unicode/MBCS的_tcscpy)的第二個參數是 const wchar_t* (Unicode)或const char* (ANSI),系統編譯器將會自動對其進行轉換。
  方法三,使用CString::GetBuffer。例如:
CString s(_T("This is a test "));
LPTSTR p = s.GetBuffer();
// 在這里添加使用p的代碼
if(p != NULL) *p = _T('\0');
s.ReleaseBuffer();
// 使用完后及時釋放,以便能使用其它的CString成員函數
  (3) BSTR轉換成char*
  方法一,使用ConvertBSTRToString。例如:
#include
#pragma comment(lib, "comsupp.lib")
int _tmain(int argc, _TCHAR* argv[]){
BSTR bstrText = ::SysAllocString(L"Test");
char* lpszText2 = _com_util::ConvertBSTRToString(bstrText);
SysFreeString(bstrText); // 用完釋放
delete[] lpszText2;
return 0;
}
  方法二,使用_bstr_t的賦值運算符重載。例如:
_bstr_t b = bstrText;
char* lpszText2 = b;
  (4) char*轉換成BSTR
  方法一,使用SysAllocString等API函數。例如:
BSTR bstrText = ::SysAllocString(L"Test");
BSTR bstrText = ::SysAllocStringLen(L"Test",4);
BSTR bstrText = ::SysAllocStringByteLen("Test",4);
  方法二,使用COleVariant或_variant_t。例如:
//COleVariant strVar("This is a test");
_variant_t strVar("This is a test");
BSTR bstrText = strVar.bstrVal;
  方法三,使用_bstr_t,這是一種最簡單的方法。例如:
BSTR bstrText = _bstr_t("This is a test");
  方法四,使用CComBSTR。例如:
BSTR bstrText = CComBSTR("This is a test");
  或
CComBSTR bstr("This is a test");
BSTR bstrText = bstr.m_str;
  方法五,使用ConvertStringToBSTR。例如:
char* lpszText = "Test";
BSTR bstrText = _com_util::ConvertStringToBSTR(lpszText);
  (5) CString轉換成BSTR
  通常是通過使用CStringT::AllocSysString來實現。例如:
CString str("This is a test");
BSTR bstrText = str.AllocSysString();

SysFreeString(bstrText); // 用完釋放
  (6) BSTR轉換成CString
  一般可按下列方法進行:
BSTR bstrText = ::SysAllocString(L"Test");
CStringA str;
str.Empty();
str = bstrText;
  或
CStringA str(bstrText);
  (7) ANSI、Unicode和寬字符之間的轉換
  方法一,使用MultiByteToWideChar將ANSI字符轉換成Unicode字符,使用WideCharToMultiByte將Unicode字符轉換成ANSI字符。
  方法二,使用“_T”將ANSI轉換成“一般”類型字符串,使用“L”將ANSI轉換成Unicode,而在托管C++環境中還可使用S將ANSI字符串轉換成String*對象。例如:
TCHAR tstr[] = _T("this is a test");
wchar_t wszStr[] = L"This is a test";
String* str = S”This is a test”;
  方法三,使用ATL 7.0的轉換宏和類。ATL7.0在原有3.0基礎上完善和增加了許多字符串轉換宏以及提供相應的類,它具有如圖3所示的統一形式:
  其中,第一個C表示“類”,以便於ATL 3.0宏相區別,第二個C表示常量,2表示“to”,EX表示要開辟一定大小的緩沖。SourceType和DestinationType可以是A、 T、W和OLE,其含義分別是ANSI、Unicode、“一般”類型和OLE字符串。例如,CA2CT就是將ANSI轉換成一般類型的字符串常量。下面 是一些示例代碼:
LPTSTR tstr= CA2TEX<16>("this is a test");
LPCTSTR tcstr= CA2CT("this is a test");
wchar_t wszStr[] = L"This is a test";
char* chstr = CW2A(wszStr);

5.LPTSTR、LPCSTR、LPCTSTR、LPSTR的來源及意義

5.1來源

  UNICODE:它是用兩個字節表示一個字符的方法。比如字符'A'在ASCII下面是一個字符,可'A'在UNICODE下面是兩個字符,高字符用0填充,而且漢字'程'在ASCII下面是兩個字節,而在UNICODE下仍舊是兩個字節。UNICODE的用處就是定長表示世界文字,據統計,用兩個字節可以編碼現存的所有文字而沒有二義。MBCS,它是多字節字符集,它是不定長表示世界文字的編碼。

  MBCS表示英文字母時就和ASCII一樣(這也是我們容易把MBCS和ASCII搞混的原因),但表示其他文字時就需要用多字節。WINDOWS 下面的程序設計可以支持MBCS和UNICODE兩種編碼的字符串,具體用那種就看你定義了MBCS宏還是UNICODE宏。MBCS宏對應的字符串指針是char*也就是LPSTR,UNICODE對應的指針是unsigned  short*也就是LPWSTR,為了寫程序方便微軟定義了類型LPTSTR,在MBCS下他就是char*,   在UNICODE下它是unsigned   short*,這樣你就可以重定義一個宏進行不同字符集的轉換了。

5.2 LPTSTR、LPCSTR、LPCTSTR、LPSTR的意義:

LPSTR:32bit指針 指向一個字符串,每個字符占1字節

LPCSTR:32-bit指針 指向一個常字符串,每個字符占1字節
LPCTSTR:32-bit指針 指向一個常字符串,每字符可能占1字節或2字節,取決於Unicode是否定義
LPTSTR:32-bit指針 每字符可能占1字節或2字節,取決於Unicode是否定義

Windows使用兩種字符集ANSI和UNICODE,前者就是通常使用的單字節方式,但這種方式處理象中文這樣的雙字節字符不方便,容易出現半個漢字的情況。而后者是雙字節方式,方便處理雙字節字符。

WindowsNT 的所有與字符有關的函數都提供兩種方式的版本,而Windows9x只支持ANSI方式。_T一般同字常數相關,如_T("Hello"。如果你編譯一個程序為ANSI方式,_T實際不起任何作用。而如果編譯一個程序為UNICODE方式,則編譯器會把"Hello"字符串以UNICODE方式保存。_T 和_L的區別在於,_L不管你是以什么方式編譯,一律UNICODE方式保存.

L是表示字符串資源為Unicode的。比如
wchar_t Str[] = L"Hello World!";
這個就是雙子節存儲字符了。

_T是一個適配的宏~


#ifdef _UNICODE的時候
_T就是L
沒有#ifdef _UNICODE的時候
_T就是ANSI的。

比如

LPTSTR lpStr = new TCHAR[32];
TCHAR* szBuf = _T("Hello");
以上兩句使得無論是在UNICODE編譯條件下還是ANSI編譯條件下都是正確編譯的。

而且MS推薦你使用相匹配的字符串函數。
比如處理LPTSTR或者LPCTSTR 的時候,不要用strlen ,而是要用_tcslen,否則在UNICODE的編譯條件下,strlen不能處理 wchar_t*的字符串。

T是非常有意思的一個符號(TCHAR、LPCTSTR、LPTSTR、_T()、_TEXT()...),它表示使用一種中間類型,既不明確表示使用 MBCS,也不明確表示使用 UNICODE。那到底使用哪種字符集?編譯的時候才決定 

在vc++中有着各種字符串的表示法:        

首先char*   是指向ANSI字符數組的指針,其中每個字符占據8位(有效數據是除掉最高位的其他7位),這里保持了與傳統的C,C++的兼容。      

LP的含義是長指針(long   pointer)。

LPSTR是一個指向以‘/0’結尾的ANSI字符數組的指針,與char*可以互換使用,在win32中較多地使用 LPSTR。而LPCSTR中增加的‘C’的含義是“CONSTANT”(常量),表明這種數據類型的實例不能被使用它的API函數改變,除此之外,它與 LPSTR是等同的。    

    為了滿足程序代碼國際化的需要,業界推出了Unicode標准,它提供了一種簡單和一致的表達字符串的方法,所有字符中的字節都是16位的值,其數量也可以滿足差不多世界上所有書面語言字符的編碼需求,開發程序時使用Unicode(類型為wchar_t)是一種被鼓勵的做法。    

    LPWSTR與LPCWSTR由此產生,它們的含義類似於LPSTR與LPCSTR,只是字符數據是16位的wchar_t而不是char。        

 然后為了實現兩種編碼的通用,提出了TCHAR的定義:    

如果定義_UNICODE,聲明如下:     typedef   wchar_t   TCHAR;    

如果沒有定義_UNICODE,則聲明如下:     typedef   char   TCHAR;      

LPTSTR和LPCTSTR中的含義就是每個字符是這樣的TCHAR。        

CString類中的字符就是被聲明為TCHAR類型的,它提供了一個封裝好的類供用戶方便地使用。

LPTSTR、LPCSTR、LPCTSTR、LPSTR之間的轉換:


如何理解LPCTSTR類型?

L表示long指針,這是為了兼容Windows 3.1等16位操作系統遺留下來的,在win32中以及其他的32為操作系統中, long指針和near指針及far修飾符都是為了兼容的作用。沒有實際意義。P表示這是一個指針,C表示是一個常量,T表示在Win32環境中, 有一個_T宏,這個宏用來表示你的字符是否使用UNICODE, 如果你的程序定義了UNICODE或者其他相關的宏,那么這個字符或者字符串將被作為UNICODE字符串,否則就是標准的ANSI字符串,STR表示這個變量是一個字符串,所以LPCTSTR就表示一個指向常固定地址的可以根據一些宏定義改變語義的字符串。
同樣, LPCSTR就只能是一個ANSI字符串,在程序中我們大部分時間要使用帶T的類型定義。

LPCTSTR == const TCHAR *

CString 和 LPCTSTR 可以說通用。 原因在於CString定義的自動類型轉換,沒什么奇特的,最簡單的C++操作符重載而已。

常量字符串ansi和unicode的區分是由宏_T來決定的。但是用_T("abcd")時,字符串"abcd"就會根據編譯時的是否定一_UNICODE來決定是char* 還是 w_char*。 同樣,TCHAR 也是相同目的字符宏。看看定義就明白了。簡單起見,下面只介紹 ansi 的情況,unicode 可以類推。

ansi情況下,LPCTSTR 就是 const char*, 是常量字符串(不能修改的)。
而LPTSTR 就是 char*, 即普通字符串(非常量,可修改的)。
這兩種都是基本類型, 而CString 是 C++類, 兼容這兩種基本類型是最起碼的任務了。
由於const char* 最簡單(常量,不涉及內存變更,操作迅速), CString 直接定義了一個類型轉換函數 operator LPCTSTR() {......}, 直接返回他所維護的字符串。
當你需要一個const char* 而傳入了CString時, C++編譯器自動調用 CString重載的操作符 LPCTSTR()來進行隱式的類型轉換。
當需要CString , 而傳入了 const char* 時(其實 char* 也可以),C++編譯器則自動調用CString的構造函數來構造臨時的 CString對象。
因此CString 和 LPCTSTR 基本可以通用。

但是 LPTSTR又不同了,他是 char*, 意味着你隨時可能修改里面的數據,這就需要內存管理了(如字符串變長,原來的存貯空間就不夠了,則需要重新調整分配內存)。
所以 不能隨便的將 const char* 強制轉換成 char* 使用。
樓主舉的例子
LPSTR lpstr = (LPSTR)(LPCTSTR)string;
就是這種不安全的使用方法。
這個地方使用的是強制類型轉換,你都強制轉換了,C++編譯器當然不會拒絕你,但同時他也認為你確實知道自己要做的是什么。因此是不會給出警告的。
強制的任意類型轉換是C(++)的一項強大之處,但也是一大弊端。這一問題在 vc6 以后的版本(僅針對vc而言)中得到逐步的改進(你需要更明確的類型轉換聲明)。

其實在很多地方都可以看到類似
LPSTR lpstr = (LPSTR)(LPCTSTR)string;
地用法,這種情況一般是函數的約束定義不夠完善的原因,比如一個函數接受一個字符串參數的輸入,里面對該字符串又沒有任何的修改,那么該參數就應該定義成 const char*,但是很多初學者弄不清const地用法,或者是懶, 總之就是隨意寫成了 char* 。 這樣子傳入CString時就需要強制的轉換一下。

這種做法是不安全的,也是不被建議的用法,你必須完全明白、確認該字符串沒有被修改。

CString 轉換到 LPTSTR (char*), 預定的做法是調用CString的GetBuffer函數,使用完畢之后一般都要再調用ReleaseBuffer函數來確認修改 (某些情況下也有不調用ReleaseBuffer的,同樣你需要非常明確為什么這么做時才能這樣子處理,一般應用環境可以不考慮這種情況)。

同時需要注意的是, 在GetBuffer 和 ReleaseBuffer之間,CString分配了內存交由你來處理,因此不能再調用其他的CString函數。

CString 轉LPCTSTR:
CString cStr;
const char *lpctStr=(LPCTSTR)cStr;

LPCTSTR轉CString:
LPCTSTR lpctStr;
CString cStr=lpctStr;

 6.字符串與其他類型那個轉換

6.1. c++中string到int的轉換

1) 在C標准庫里面,使用atoi:

#include <cstdlib>
#include <string>

std::string text = "152";
int number = std::atoi( text.c_str() );
if (errno == ERANGE) //可能是std::errno
{
 //number可能由於過大或過小而不能完全存儲
}
else if (errno == ????)
//可能是EINVAL
{
 //不能轉換成一個數字
}

2) 在C++標准庫里面,使用stringstream:(stringstream 可以用於各種數據類型之間的轉換)

#include <sstream>
#include <string>

std::string text = "152";
int number;
std::stringstream ss;


ss << text;//可以是其他數據類型
ss >> number; //string -> int
if (! ss.good())
{
//錯誤發生
}

ss << number;// int->string
string str = ss.str();
if (! ss.good())
{
 //錯誤發生
}

3) 在Boost庫里面,使用lexical_cast:

#include <boost/lexical_cast.hpp>
#include <string>

try
{
 std::string text = "152";
 int number = boost::lexical_cast< int >( text );
}
catch( const boost::bad_lexical_cast & )
{
 //轉換失敗
}                      

6.2.string 轉 CString
CString.format(”%s”, string.c_str());
用c_str()確實比data()要好;

6.3.char 轉 CString
CString.format(”%s”, char*);

6.4.char 轉 string
string s(char *);
只能初始化,在不是初始化的地方最好還是用assign().

6.5.string 轉 char *
char *p = string.c_str();

6.6.CString 轉 string
string s(CString.GetBuffer());
GetBuffer()后一定要ReleaseBuffer(),否則就沒有釋放緩沖區所占的空間.

6.7.字符串的內容轉換為字符數組和C—string
(1)  data(),返回沒有”\0“的字符串數組
(2)  c_str(),返回有”\0“的字符串數組
(3)  copy()

6.8.CString與int、char*、char[100]之間的轉換

(1) CString互轉int

將字符轉換為整數,可以使用atoi、_atoi64或atol。而將數字轉換為CString變量,可以使用CString的Format函數。如
CString s;
int i = 64;
s.Format(”%d”, i)
Format函數的功能很強,值得你研究一下。

void CStrDlg::OnButton1()
{
   CString
   ss=”1212.12″;
   int temp=atoi(ss);
   CString aa;
   aa.Format(”%d”,temp);
   AfxMessageBox(”var is ” + aa);
}

(2) CString互轉char*

///char * TO cstring
CString strtest;
char * charpoint;
charpoint=”give string a value”; //?
strtest=charpoint;

///cstring TO char *
charpoint=strtest.GetBuffer(strtest.GetLength());

(3) 標准C里沒有string,char *==char []==string, 可以用CString.Format(”%s”,char *)這個方法來將char *轉成CString。
    要把CString轉成char *,用操作符(LPCSTR)CString就可以了。
    CString轉換 char[100]
   char a[100];
   CString str(”aaaaaa”);
   strncpy(a,(LPCTSTR)str,sizeof(a));

 引用自:http://blog.sina.com.cn/s/blog_7a4030010100rjf1.html

引用自:http://www.cnblogs.com/fire-phoenix/archive/2010/09/04/1818248.html

引用自:http://www.cnblogs.com/chuncn/archive/2009/02/24/1397518.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM