TSINGSEE青犀視訊開發AI智慧分析採用c++中文編碼出現亂碼問題是由什麼導致的
阿新 • • 發佈:2021-12-17
EasyCVR的AI智慧分析版本在做研發的時候,就受到了很多朋友的關注,EasyCVR的人臉識別功能採用了Go語言,使用c/c++ 的標頭檔案和dll檔案。在C++ 中如果出現中文,會出現亂碼的問題,使用notepad++開啟儲存的二進位制檔案,出現亂碼。
正常的情況選擇UTF8編碼正常顯示:
在計算機的內部,所有的資料都是以二進位制的形式儲存的,在儲存文字時,需要將文字檔案的資訊都轉換為二進位制進行儲存,而現實是將二進位制轉換為文字顯示,所以編碼就是以二進位制和顯示字元直接轉換。
- ASCII碼:是美國製定的一套字元編碼,主要用來顯示英文字元。
- GBK:ASCII編碼只適合顯示英文字元,但是對中文有6000多個常用漢字,一個位元組的大小完全不夠用。所以制定GBK標準。用二個位元組來表示中文。
- ASNI:除了中國以外,其他的許多國家頁都制定自己的編碼標準。
- Unicode:由於不同的ANSI編碼之間互不相容,這樣進行資訊互動就會進行編碼轉換。為了解決這個問題,又制定Unicode編碼,用二個位元組統一表示所有字元。
- UTF-8:Unicode可以表示所有的字元,但是英文字元也與其他字元一樣,使用兩個位元組進行編碼,使得在儲存英文文字的時候會多出一倍的儲存空間,而大多數的文字資訊都是英文的。所以UTF-8是一種可變長的編碼方式。
多位元組到寬位元組的轉換:
setlocale(LC_ALL, "");
size_t requiredSize = mbstowcs(nullptr, w, 0);
wszClassName = new WCHAR[requiredSize + 1];
memset(wszClassName, 0x00, sizeof(wszClassName));
if (static_cast<size_t>(-1) == mbstowcs(wszClassName, w, requiredSize + 1))
{
std::cout << "fail" << std::endl;
return -1;
}
else
{
std::wcout << "success: " << wszClassName << std::endl;
}
return 0;
複製程式碼
UTF-8編碼轉GBK,在vs中列印輸出:
std::wstring UT2WC(const char* buf)
{
int len = MultiByteToWideChar(CP_UTF8, 0, buf, -1, NULL, 0);
std::vector<wchar_t> unicode(len);
MultiByteToWideChar(CP_UTF8, 0, buf, -1, &unicode[0], len);
return std::wstring(&unicode[0]);
}
std::string ws2s(const std::wstring& ws)
{
std::string curLocale = setlocale(LC_ALL, NULL);
setlocale(LC_ALL, "chs");
const wchar_t* _Source = ws.c_str();
size_t _Dsize = 2 * ws.size() + 1;
char *_Dest = new char[_Dsize];
memset(_Dest, 0, _Dsize);
wcstombs(_Dest, _Source, _Dsize);
std::string result = _Dest;
delete[]_Dest;
setlocale(LC_ALL, curLocale.c_str());
return result;
}
複製程式碼
Unicode、ANSI和UTF之間的轉換:
std::string UnicodeToUTF8(const std::wstring & wstr)
{
std::string ret;
try {
std::wstring_convert< std::codecvt_utf8<wchar_t> > wcv;
ret = wcv.to_bytes(wstr);
}
catch (const std::exception & e) {
std::cerr << e.what() << std::endl;
}
return ret;
}
std::wstring UTF8ToUnicode(const std::string & str)
{
std::wstring ret;
try {
std::wstring_convert< std::codecvt_utf8<wchar_t> > wcv;
ret = wcv.from_bytes(str);
}
catch (const std::exception & e) {
std::cerr << e.what() << std::endl;
}
return ret;
}
std::string UnicodeToANSI(const std::wstring & wstr)
{
std::string ret;
std::mbstate_t state = {};
const wchar_t *src = wstr.data();
size_t len = std::wcsrtombs(nullptr, &src, 0, &state);
if (static_cast<size_t>(-1) != len) {
std::unique_ptr< char[] > buff(new char[len + 1]);
len = std::wcsrtombs(buff.get(), &src, len, &state);
if (static_cast<size_t>(-1) != len) {
ret.assign(buff.get(), len);
}
}
return ret;
}
std::wstring ANSIToUnicode(const std::string & str)
{
std::wstring ret;
std::mbstate_t state = {};
const char *src = str.data();
size_t len = std::mbsrtowcs(nullptr, &src, 0, &state);
if (static_cast<size_t>(-1) != len) {
std::unique_ptr< wchar_t[] > buff(new wchar_t[len + 1]);
len = std::mbsrtowcs(buff.get(), &src, len, &state);
if (static_cast<size_t>(-1) != len) {
ret.assign(buff.get(), len);
}
}
return ret;
}
作者:TSINGSEE
連結:https://juejin.cn/post/7041806412866912292/
來源:稀土掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。