QString與各種字符串之間的轉化

 

QString與char *的相互轉化
QString str1 = "Test";
QByteArray ba = str1.toLatin1();
const char *c_str2 = ba.data();
printf("str2: %s", c_str2);
QString string = QString(QLatin1String(c_str2)) ;
或者


//中文Windows的缺省內碼是GBK
// ASCII、GB2312、GBK到GB18030的編碼方法是向下兼容的。而Unicode只與ASCII兼容(更準確地說,是與
// ISO-8859-1兼容),與GB碼不兼容。例如“漢”字的Unicode編碼是6C49,而GB碼是BABA。

#define G2U(s) ( QTextCodec::codecForName("GBK")->toUnicode(s) )
#define U2G(s) ( QTextCodec::codecForName("GBK")->fromUnicode(s) )
QString str;
QCString cstr;
str = G2U("中文輸入");
cstr = U2G(str);

▲qstring ->std::string
qstring::toStdString() ,qstring::toStdWString()

▲ BSTR<->qstring
typedef WCHAR OLECHAR;  typedef OLECHAR *BSTR;
BSTR(Basic STRing,Basic字符串)是一個OLECHAR*類型的Unicode字符串。它被描述成一個與自動化相兼容的類型。由於操作系統提供相應的API函數(如SysAllocString)來管理它以及一些默認的調度代碼,因此BSTR實際上就是一個COM字符串,但它卻在自動化技術以外的多種場合下得到廣泛使用。LPSTR和LPWSTR是Win32和VC++所使用的一種字符串數據類型。LPSTR被定義成是一個指向以NULL(‘\0’)結尾的8位ANSI字符數組指針,而LPWSTR是一個指向以NULL結尾的16位雙字節字符數組指針。
BSTR bstr_str;
qstring q_str((QChar*)bstr_str, wcslen(bstr_str))
bstr_str = SysAllocString(q_str.utf16())

▲ qstring<->LPCSTR
qstring::toLocal8Bit().constData()
QString fromLocal8Bit ( const char * str, int size = -1 )

▲ qstring<->LPCWSTR
qstring::utf16()
QString fromUtf16 ( const ushort * unicode, int size = -1 )

▲ qstring<->CString
CString c_str(qstring::utf16())
QString fromUtf16 (LPCTSTR(c_str) )  
CString cstr1 = "ASDDSD";
int strLength = cstr1.GetLength() + 1;
char *pValue = new char[strLength];
strncpy(pValue, cstr1, strLength);

以下引用的一個例子告訴我在不同的字符集字符串表示的不同

CString m_message("Hello!");
char szBuffer[4096];
memcpy( szBuffer, m_message, m_message.GetLength() );

發現輸出szBuffer 的結果是"H",匪夷所思。
然後試了試常用的CString TO char的其他手段。

CString m_message("Hello!");
char *szBuffer = m_message.GetBuffer( m_message.GetLength() );

結果szBuffer指向"H"。
這就是說用CString給char賦值,是直接把第一個給char麼?
答案出乎人意料,可以說是的,參閱《windows程序設計第5版》中的Unicode簡介,可以得出這個結論。'H'的Unicode表示是一個雙字節值0x0048。然而,因爲Intel微處理器從最小的字節開始儲存多字節數值,該字節實際上是以0x48、0x00的順序保存在內存中。
字符串"Hello!"的Unicode表示爲:

0x0048 0x0065 0x006C 0x006C 0x006F 0x0021

它在計算機裏的存儲爲:

48 00 65 00 6C 00 6C 00 6F 00 21 00

這就是說當他傳遞給char時,賦值時讀到第二個字節00時就會當作'\0'截斷掉後面的數據了。所以CString“Hello!”賦值給char字符串當然是“H”了。
可是當使用VC6.0時這個問題卻不存在。那是因爲VC6.0默認使用的字符集是ANSI編碼,而VS2008默認使用的是多字節字符集。這個可以在項目->工程屬性->常規->字符集裏設置。
若改成多字節字符集,上述代碼就沒問題了。
當然也可以不改字符集來解決這個代碼。在字符串類中,有如下對應關係:
字符串類      字符集   賦值函數

CStringA       char           strcpy
CStringW     WCHAR      wcscpy
CString        _TCHAR     _tcscpy

#ifdef _UNICODE
        typedef wchar_t TCHAR    ;
#else
        typedef char TCHAR;
#endif

CStringA是任何字符集設置下都是用多字節字符集,CStirngW是任何設置下都是用寬字符集(Unicode),CString就是視編譯器設置而定。故可以這麼修改代碼:

CStringA m_message("Hello!");
char szBuffer[4096];
strcpy( szBufer, m_message);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章