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);

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