有关Unicode Ansi Utf-8 Utf-16之前的关系以及互相转换函数的实现

在一位朋友的帮助下我有了以下理解,不一定全对但能够疏通他们之间的关系 

Ansi

是一种规范定义1-128固定的全球统一的ANSI码表

然后各国在128 后面定义自己国家的文字

 如:中

Ansi:D6D0

Ansi缺点各国编码有冲突没法通信 同样的编码在这个国家是这个字那个国家是那个字比如我们经常在国外下个代码回来打开一看

全都是乱码为了解决这个问题必须要统一所以有了

 

Unicode

【注意:是一种规范不是一种编码】

他定义了全球文字的代码点一共分为17组,他是无限可扩展的没有上限给每全球各国的字都字义一个索引

以后如果我们引入外星人文字也可以用Unicode向后扩展 打个比方哈哈!他只是规范不是编码

有了上面的规范那就可以定义编码了

 

Utf-16

这个就是真正的编码了代码点是2个字节的就用2字节表示 如果是3个字节的就用4字节表示 如果表示ANSI 1-128范围的就用1字节另一个字用00代替(这步就出现问题了下面说) 

 如:中

代码点:U+4E2D

Utf-16 :4E2D

Utf-8:E4B8AD

查编码范围  https://blog.csdn.net/qq_22520587/article/details/62454354

这个网站可以查编码  https://unicode-table.com/en/search/?q=中

 

Utf-8

另一种编码方式 他用1字节表示Ansi和Ansi一样的编码其它字用3字节表示包含目前全球所有文字

他的最大优势就是解决Utf-16说到的问题 Utf-8和Ansi一样在表示一个字符串时判断遇到00表示字符串就结束了

如果是Utf-16要用00 00才能判断出字符串结束了,所以Utf-8最大优势就是和Ansi兼容

在编程中我们可以直接用char *(Delphi 是PAnsiChar)指针 指向Utf-8的字符串 遇到00就是字符串结束的位置

如果是Utf-16 只能用wchar_t *(Delphi 是PWideChar)指向他 遇到 00 00 才是字符串结束符

 

我曾经错误的认识:

Windows API 中只要是涉及到字符串的API经常有两个版本 xxxxA  xxxxW用最后A和W来区分

A是Ansi    W经常说的就是这是Unicode【这里严格来说应该是Utf-16 Unicode只是规范不是编码Utf-16才是编码】

【Windows API中的W全都是Utf-16】

有关转换函数的正确理解

他的第一个参数

CP_ACP:ANSI代码页;

CP_MACCP:Macintosh代码页;

CP_OEMCP:OEM代码页;

CP_SYMBOL:符号代码页(42);

CP_THREAD_ACP:当前线程ANSI代码页;

CP_UTF7:使用UTF-7转换;

CP_UTF8:使用UTF-8转换。

常用的就只有两个 CP_ACP   CP_UTF8

刚开始我不太明白这个到底指定的是输入参数还是输出参数

后来我看MSDN上函数的说明他是一个Utf-16的相互换转函数才明白

MultiByteToWideChar        xxxx -> UTF-16

WideCharToMultiByte        UTF-16 -->  xxxx

就是说第一个参数其实是指定的那个xxxx的类型

 

函数互相转换这里就引用别人的出处

https://blog.csdn.net/bajianxiaofendui/article/details/83302855

std::wstring AnsiToUTF16(const std::string &strAnsi)
{
	//获取转换所需的接收缓冲区大小
	int  nUnicodeLen = ::MultiByteToWideChar(CP_ACP,  0,  strAnsi.c_str(),  -1,  NULL,  0);
	//分配指定大小的内存
	wchar_t* pUnicode = new wchar_t[nUnicodeLen + 1];
	memset((void*)pUnicode, 0, (nUnicodeLen + 1) * sizeof(wchar_t));
	//转换
	::MultiByteToWideChar(CP_ACP,  0,  strAnsi.c_str(),  -1,  (LPWSTR)pUnicode,  nUnicodeLen);
	std::wstring  strUnicode;
	strUnicode = (wchar_t*)pUnicode;
	delete[]pUnicode;
	return strUnicode;
}

std::string UTF16ToANSI(const std::wstring& strUnicode)
{
	int nAnsiLen = WideCharToMultiByte(CP_ACP,  0,  strUnicode.c_str(),  -1,  NULL,  0,  NULL,  NULL);
	char *pAnsi = new char[nAnsiLen + 1];
	memset((void*)pAnsi, 0, (nAnsiLen + 1) * sizeof(char));
	::WideCharToMultiByte(CP_ACP,  0,  strUnicode.c_str(),  -1,  pAnsi,  nAnsiLen,  NULL,  NULL);
	std::string strAnsi;
	strAnsi = pAnsi;
	delete[]pAnsi;
	return strAnsi;
}

std::wstring UTF8ToUTF16(const std::string& str)
{
	int nUnicodeLen = ::MultiByteToWideChar(CP_UTF8,  0,  str.c_str(),  -1,  NULL,  0);
	wchar_t*  pUnicode;
	pUnicode = new wchar_t[nUnicodeLen + 1];
	memset((void*)pUnicode, 0, (nUnicodeLen + 1) * sizeof(wchar_t));
	::MultiByteToWideChar(CP_UTF8,  0,  str.c_str(),  -1,  (LPWSTR)pUnicode,  nUnicodeLen);
	std::wstring  strUnicode;
	strUnicode = (wchar_t*)pUnicode;
	delete []pUnicode;
	return strUnicode;
}

std::string UTF16ToUTF8(const std::wstring& strUnicode)
{
	int nUtf8Length = WideCharToMultiByte(CP_UTF8,  0,  strUnicode.c_str(),  -1,  NULL,  0,  NULL,  NULL);
	char* pUtf8 = new char[nUtf8Length + 1];
	memset((void*)pUtf8, 0, sizeof(char) * (nUtf8Length + 1));
	::WideCharToMultiByte(CP_UTF8,  0,  strUnicode.c_str(),  -1,  pUtf8,  nUtf8Length,  NULL,  NULL);
	std::string strUtf8;
	strUtf8 = pUtf8;
	delete[] pUtf8;
	return strUtf8;
}

std::string AnsiToUtf8(const std::string &strAnsi)
{
	std::wstring strUnicode = AnsiToUnicode(strAnsi);
	return UnicodeToUTF8(strUnicode);
}

std::string Utf8ToAnsi(const std::string &strUtf8)
{
	std::wstring strUnicode = UTF8ToUnicode(strUtf8);
	return UnicodeToANSI(strUnicode);
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UTF-8是一种可变长度的Unicode编码方式,而ANSI是一种字符编码方式。要将UTF-8格式转换ANSI格式,需要使用特定的工具或编程语言来实现。 在Python中,可以使用编码函数实现UTF-8转换ANSI。首先,我们需要读取以UTF-8编码的文件或字符串,并指定编码为'utf-8'。然后,我们将其使用编码函数进行转换并指定目标编码为'ansi'。 以下是一个示例代码: ```python # 导入codecs模块 import codecs # 以UTF-8编码读取文件内容 with codecs.open('input.txt', 'r', 'utf-8') as file: utf8_content = file.read() # 将UTF-8转换ANSI编码 ansi_content = utf8_content.encode('ansi') # 将ANSI内容写入新文件 with codecs.open('output.txt', 'w', 'ansi') as file: file.write(ansi_content) ``` 在上面的示例中,我们首先使用'codecs.open'函数以'utf-8'编码读取名为'input.txt'的文件内容,并将其存储在变量'utf8_content'中。然后,我们使用编码函数'encode'将'utf8_content'转换ANSI编码的内容,并将结果存储在变量'ansi_content'中。最后,我们将'ansi_content'使用'codecs.open'函数以'ansi'编码写入名为'output.txt'的新文件中。 请注意,在进行编码转换时,可能会出现字符无法完全转换或出现乱码的情况。这是因为ANSI编码方式可能无法表示UTF-8中某些特殊字符或语言特定的字符。因此,在转换编码时,需要确认目标编码是否支持源内容中使用的所有字符。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值