亂碼包含兩種一種是我們保存的文件在不同的系統(tǒng)中打開時候是亂碼的吴侦,一種是在網(wǎng)絡(luò)通信的時候接收的數(shù)據(jù)時候亂碼的。
第一種解決方法
Visual Studio (中文版)默認(rèn)保存的文本文件是GB2312
編碼(代碼頁936)的谆扎,默認(rèn)的行尾(End of line)是CRLF的银室。
如果僅僅是在windows下開發(fā)問題也不大枕面,但是涉及到跨平臺開發(fā)的時候,就不是很滿意了政钟。
VS本身的 文件 -> 高級保存選項(xiàng) 中是可以選擇保存的編碼和行尾的路克,但是不支持為默認(rèn)的樟结。
還有一個問題是cl
編譯的時候,對utf-8
格式支持不好(需要添加/source-charset:utf-8
選項(xiàng)精算,默認(rèn)是當(dāng)作本地字符集的)瓢宦,對于帶BOM
標(biāo)記的文件則沒有問題。
所以我們在項(xiàng)目中統(tǒng)一規(guī)定使用UTF-8 with BOM
編碼殖妇,行尾為LF
(\n)刁笙。
這里介紹兩個插件
ForceUTF8 (with BOM)
這個插件還有兩個版本,一個是帶BOM
的谦趣,一個是不帶的疲吸。
插件是開源的,代碼很簡單前鹅。就是在文檔保存的時候摘悴,判斷是否是文本文件。如果是的話舰绘,那就先轉(zhuǎn)編碼為UTF-8 with BOM
蹂喻,再寫入文件。
下載地址 https://marketplace.visualstudio.com/items?itemName=jz5.ForceUTF8withBOM
其實(shí)可以直接在這個項(xiàng)目上改捂寿,在保存文件前把\r\n
口四、\r
、\n
都替換為\n
即可(要注意替換次序)秦陋。
Line Endings Unifier
這個插件用來統(tǒng)一行尾蔓彩。
可以設(shè)置針對的文件和目標(biāo)行尾。它也是開源的驳概。
下載地址 https://marketplace.visualstudio.com/items?itemName=JakubBielawa.LineEndingsUnifier
第二種:
當(dāng)我們接收到含有中文的字符串亂碼的時候如果能保證發(fā)過來的是utf-8
這里我們可以把utf-8轉(zhuǎn)為vs使用的編碼類型
這里提供兩個函數(shù)用于相互轉(zhuǎn)換:
1. utf8轉(zhuǎn)std::string
轉(zhuǎn)換過程:先將utf8轉(zhuǎn)雙字節(jié)Unicode編碼赤嚼,再通過WideCharToMultiByte將寬字符轉(zhuǎn)換為多字節(jié)。
//-----------------------------------------------------------------------
std::string UTF8_To_string(const std::string & str)
{
int nwLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
wchar_t * pwBuf = new wchar_t[nwLen + 1];//一定要加1顺又,不然會出現(xiàn)尾巴
memset(pwBuf, 0, nwLen * 2 + 2);
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), pwBuf, nwLen);
int nLen = WideCharToMultiByte(CP_ACP, 0, pwBuf, -1, NULL, NULL, NULL, NULL);
char * pBuf = new char[nLen + 1];
memset(pBuf, 0, nLen + 1);
WideCharToMultiByte(CP_ACP, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);
std::string retStr = pBuf;
delete []pBuf;
delete []pwBuf;
pBuf = NULL;
pwBuf = NULL;
return retStr;
}
// translate ascii characters to utf-8 characters
2.std::string轉(zhuǎn)utf8字符串
轉(zhuǎn)換過程:與1過程相反
//------------------------------------------------------------------------
std::string string_To_UTF8(const std::string & str)
{
int nwLen = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
wchar_t * pwBuf = new wchar_t[nwLen + 1];//一定要加1更卒,不然會出現(xiàn)尾巴
ZeroMemory(pwBuf, nwLen * 2 + 2);
::MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), pwBuf, nwLen);
int nLen = ::WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, NULL, NULL, NULL);
char * pBuf = new char[nLen + 1];
ZeroMemory(pBuf, nLen + 1);
::WideCharToMultiByte(CP_UTF8, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);
std::string retStr(pBuf);
delete []pwBuf;
delete []pBuf;
pwBuf = NULL;
pBuf = NULL;
return retStr;
}