• TSINGSEE青犀视频开发AI智能分析采用c++中文编码出现乱码问题是由什么导致的


    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/
    来源:稀土掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    679 怎样杀死害虫?(对付一个系统最好的方式是“围城必阙”)
    678 "流浪地球"为什么是个好地方?(系统越复杂拥有好运气的机会也就越大)
    677 人类为什么会养猫?(做一件事理性的原因的背后往往还隐藏着自己都不曾发现的感性原因)
    职场人必知的三原则
    677 怎样当一个少数派?(越在意,越出众)
    675 为什么会有“黑天鹅”?(行为和对行为后果的负责与否决定了很多黑天鹅出现概率)
    不做特殊论者(没有所谓的理所当然,你所谓的成功很有可能只是因为运气)
    事实和观点(就事论事,事实有真假,观点无对错)
    一个程序员的价值观总结
    669 创新也是搞政治?(如何创新)
  • 原文地址:https://www.cnblogs.com/TSINGSEE/p/15702320.html
Copyright © 2020-2023  润新知