dxf写入 、 dwg解析 中文乱码问题 原创
原因
中文乱码是因为dxf文件为utf8格式的,而读取的是ansi格式的,所以导致乱码
解决方法 [C++]c++utf-8和ansi的互转
在C++中,UTF-8和ANSI(特别是在Windows平台上,通常指的是系统的本地代码页,如Windows-1252或GBK等)之间的转换并不是由标准C++库直接支持的。不过,你可以使用Windows API或者第三方库(如ICU、Boost.Locale等)来实现这种转换。
使用Windows API
Windows API提供了MultiByteToWideChar和WideCharToMultiByte函数,可以用来在UTF-16(宽字符,Windows内部使用的Unicode编码)和其他编码(包括ANSI)之间进行转换。然而,由于UTF-8是基于字节的编码,你需要先将UTF-8转换为UTF-16(如果需要的话),然后再从UTF-16转换到ANSI,或者反过来。
下面是一个示例,展示了如何使用Windows API将UTF-8字符串转换为ANSI字符串:
cpp
#include <windows.h>
#include <iostream>
#include <vector>
std::string Utf8ToAnsi(const std::string& utf8) {
int nChars = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, NULL, 0);
std::wstring wstrTo(nChars, L'\0');
MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, &wstrTo[0], nChars);
int nAnsiChars = WideCharToMultiByte(CP_ACP, 0, wstrTo.c_str(), -1, NULL, 0, NULL, NULL);
std::vector<char> ansi(nAnsiChars, 0);
WideCharToMultiByte(CP_ACP, 0, wstrTo.c_str(), -1, &ansi[0], nAnsiChars, NULL, NULL);
return std::string(ansi.begin(), ansi.end());
}
int main() {
std::string utf8Str = u8"你好,世界!";
std::string ansiStr = Utf8ToAnsi(utf8Str);
std::cout << "UTF-8: " << utf8Str << std::endl;
std::cout << "ANSI: " << ansiStr << std::endl;
return 0;
}
请注意,CP_ACP是Windows中用于表示当前ANSI代码页的宏。如果你的应用程序需要在不同的系统上运行,并且需要明确指定ANSI代码页(比如总是使用Windows-1252),你应该使用相应的代码页ID(如1252)替换CP_ACP。
使用第三方库
如果你不想依赖Windows API,或者你的应用程序需要在非Windows平台上运行,那么使用第三方库可能是一个更好的选择。例如,ICU(International Components for Unicode)是一个广泛使用的、支持多种平台和语言的Unicode和全球化支持库。
使用ICU进行UTF-8和ANSI之间的转换会涉及到更多的设置和API调用,但它提供了更强大和灵活的文本处理功能。
注意
当你在不同编码之间转换文本时,一定要注意潜在的字符丢失或替换问题。特别是从UTF-8(一个能够表示世界上几乎所有字符的编码)转换到某些ANSI编码时,如果ANSI编码不支持某些字符,这些字符可能会被替换为问号(?)或其他占位符。
如果你在Windows以外的平台上工作,那么“ANSI”这个术语可能不再适用,因为不同的操作系统可能有不同的默认编码。在这种情况下,你可能需要明确指定你想要的编码(如UTF-8、ISO-8859-1等)。
dwg中文 utf8 转gbk
GBK编码(又称国标扩展码或汉字内码扩展规范)是一种用于简体中文的字符编码标准,它主要用于在中国大陆地区。GBK编码是GB2312编码的扩展,兼容GB2312编码,同时它增加了更多的汉字和符号,从而支持更多的中文字符。
主要特点
扩展性:GBK编码在GB2312的基础上进行了扩展,支持更多的汉字和符号,总共包含21886个汉字和图形符号。
兼容性:GBK编码向下兼容GB2312编码,即所有GB2312中的字符在GBK中都有相同的编码。
应用范围:在中国大陆地区,GBK编码广泛应用于Windows操作系统、部分Linux发行版、以及很多软件和互联网应用中。
编码范围
GBK编码使用双字节来表示一个字符,其编码范围从0x8140到0xFEFE,其中:
0x8140-0xA0FE:第一字节在0x81-0xFE之间,第二字节在0x40-0xFE之间,覆盖绝大多数常用汉字和符号。
0xA1A1-0xFEFE:第一字节和第二字节均在0xA1-0xFE之间,主要用于表示扩充的汉字和图形符号。
与其他编码的关系
GB2312:GBK是GB2312的超集,兼容GB2312的所有字符。
GB18030:GB18030是GBK的超集,进一步扩展了字符集,支持更多的汉字和符号,包括一些少数民族的文字和符号。GB18030也兼容GBK和GB2312。
UTF-8:UTF-8是一种针对Unicode的可变长度字符编码,它能够用一至四个字节表示任何Unicode字符(包括世界上几乎所有的字符)。与GBK不同,UTF-8是一种国际化的编码标准,不局限于任何一种语言或字符集。
使用场景
在需要进行中文处理的应用程序中,如果主要面向中国大陆用户,GBK编码是一个常见的选择。然而,随着国际化的推进和Unicode的普及,越来越多的应用程序开始采用UTF-8编码来处理多语言文本。在Web开发中,UTF-8已成为推荐使用的字符编码标准。
class codecvt_gbk : public std::codecvt_byname<wchar_t, char, std::mbstate_t>
{
public:
codecvt_gbk()
#ifdef WINDOWS
:codecvt_byname("zh_CN")
#else
: codecvt_byname("zh_CN.GBK")
#endif
{
}
};
static std::wstring_convert<codecvt_gbk> s_GbkConvert;
static std::wstring_convert<std::codecvt_utf8<wchar_t>> s_Utf8Convert;
std::string Utf8ToGbk(const std::string& str)
{
return s_GbkConvert.to_bytes(s_Utf8Convert.from_bytes(str));
}