1、通過Python3示例探索常用字符串編碼
下面,我們通過Python3代碼來了解一下字符串編碼的小秘密:
首先,我們定義一個字符串aha123
aha123 = "啊哈123"
然后,我們看看它在各種編碼下的二進制:
UTF8
aha123.encode('utf8')
b'\xe5\x95\x8a\xe5\x93\x88123'
ANSI
aha123.encode('gbk')
b'\xb0\xa1\xb9\xfe123'
Unicode
aha123.encode('unicode_escape')
b'\\u554a\\u54c8123'
小結
計算機中儲存的信息都是用二進制數表示的;而我們在屏幕上看到的英文、漢字等字符是二進制數轉換之后的結果。通俗的說,按照何種規則將字符存儲在計算機中,如'a'用什么表示,稱為"編碼";反之,將存儲在計算機中的二進制數解析顯示出來,稱為"解碼",如同密碼學中的加密和解密。在解碼過程中,如果使用了錯誤的解碼規則,則導致'a'解析成'b'或者亂碼。[1]
從上面的代碼可以看出,編碼是一種映射方式,它將字符串轉換成了不同的二進制值,其中
gbk,utf8
對應於(unsigned )char[-128,128] [0,255]
;\(f:string \to uchar\)unicode
對應於(unsigned )short[-32768,32768] [0,65535]
;;\(f:string \to ushort\)
def dump_content_codings(content):
print('原文 :',content)
print('utf8 :', content.encode('utf8'))
print('gbk :', content.encode('gbk'))
print('unicode:', content.encode('unicode_escape'))
dump_content_codings('aha123')
dump_content_codings(aha123)
原文 : aha123
utf8 : b'aha123'
gbk : b'aha123'
unicode: b'aha123'
原文 : 啊哈123
utf8 : b'\xe5\x95\x8a\xe5\x93\x88123'
gbk : b'\xb0\xa1\xb9\xfe123'
unicode: b'\\u554a\\u54c8123'
2、Qt5中使用QTextCodec進行編碼轉換
Qt使用Unicode來存儲、繪制和操作字符串。
Qt提供了一組QTextCodec類來幫助在Unicode和非Unicode格式之間進行轉換。您還可以創建自己的編解碼器類。[2]
void string_coding_test() {
std::string aha_u8 = u8"啊哈123";
QTextCodec* utf8_codec = QTextCodec::codecForName("UTF-8");
QTextCodec* gbk_codec = QTextCodec::codecForName("GBK");
// UTF8 -> Unicode,首先將utf8轉換成內置的unicode(QString)
QString aha_unicode = utf8_codec->toUnicode(aha_u8.c_str());
// Unicode -> gbk,再從unicode轉換成gbk
std::string aha_gbk = gbk_codec->fromUnicode(aha_unicode);
// 以下代碼用於顯示轉換后的二制內容以及保存的文本文件內容
for (auto& i : aha_gbk)
{
if ('0' <= i && i <= '9')
std::cout << i;
else
std::cout << "\\x" << std::hex << short(i);
}
std::cout << std::endl ;
{
std::string sPath = "text_gbk.txt";
std::ofstream file(sPath);
file << aha_gbk << std::endl;
}
// Unicode -> utf8,又從unicode轉換成utf-8
std::string aha_u8_2 = utf8_codec->fromUnicode(aha_unicode);
// 以下代碼用於顯示轉換后的二制內容以及保存的文本文件內容
for (auto& i : aha_u8_2)
{
if ('0' <= i && i <= '9')
std::cout << i;
else
std::cout << "\\x" << std::hex << short(i);
}
{
std::string sPath = "text_u8.txt";
std::ofstream file(sPath);
file << aha_u8 << std::endl;
}
}
小結
在Qt5中,先將字符串保存為QString(Unicode),然后,再通過QTextCodec,將Unicode轉換成其它編碼的字符串。