字符集、codepages、setlocal

关于字符集

  • UTF-8编码文本在VS中乱码解析
  • 字符集简介
  • Unicode结构
  • code pages
  • wstring与string相互转换

UTF-8编码文本在VS中乱码解析

windows操作系统中,Unicode字符集用UTF-16实现的,ANSI字符集是根据代码页中设置相关,默认没有用UTF-8,VS读取UTF-8编码的文本文件时,如果遇到中文,不论用string的ANSI解析,还是用wstring的Unicode解析,均会乱码。

字符集简介

一种“字符集”就是字符到内码的映射。目前用得最广泛的就是Unicode,UTF-8是UNICODE的一种实现方式,UNICODE在windows 系统内部用UTF-16实现。用UTF-16,大多数字符能被两个字节代码标识。

编程中发现一些第三方库必须要使用老的字符集。code pages允许应用程序工作在这些老的字符集环境下。老字符集可分为:
1、单字节字符集(SBCS),例如ASCII
2、多字节字符集,特别是双字节字符集(DBCS),例如GBK
注:ASCII、GBK、BIG5等都属于ANSI编码。

Unicode结构

Unicode字符集也被称为Universal Character Set(UCS)。UCS分为UCS-2和UCS-4。UCS-4,4个字节,最高位必为0,UCS-4最高字节7个有效位,128个组合,每个组根据次高字节可分为256个plane。Group 0的Plane 0被称作Basic Multilingual Plane,即BMP。

UTF-16用16位直接表示65536个独立字符,但是BMP不能全部覆盖所有字符。Unicode4.1包括了97000个字符。 Unicode标准建立了16个附加的字符plane,每一个大小都与BMP一样(BMP正是group,plane都为0)。尽管超出BMP的二进制代码没有字符与其一一对应,但是理论上说Unicode可以定义1114112个字符(2¹⁶ * 17),范围为:U+0000到U+10FFFF.

Unicode定义 Supplementary Characters来用UTF-16代表这个大的字符集。关于Supplementary Characters可参考 [ MSDN ]

Code Pages

Code Pages就是unicode与各国文字之间的映射表。前面提到字符集就是字符到内码的映射,Unicode要想转老字符集,就是将按Unicode存放的字符转换到对应老字符集对应的内码,code page就是规定你是按简体中文转,还是按法文转,还是按繁体中文转,但是必须系统支持才能有效。
vs里面通过setlocal指定codepage。值得注意的是,中文windows系统默认的是GBK编码。setlocal操作与下图操作等效。

这里写图片描述

wstring与string相互转换

///
// wcstombs_s : 此函数转换后最后一个字符始终是null-结束符,
// 因此如果要转换的字符串是“中文”, sizeInByte设置为2,则不能正确转换
// sizeInByte设置为3,可以转换“中”字
// sizeInByte是目标bugggfer的长度!

// 转换终止的3个条件:
// 1 碰到null结束符,也就是说,源字符串转换完毕
// 2 碰到宽字符不能转换的情况
// 3 buffer里面存的字符长度(byte)等于count, 也就是说填满了
//
//wstring to string
string ws2s(wstring& in)
{
	// 设置code page
	setlocale(LC_ALL, "chs");

	// 源字符串以及尺寸
	const wchar_t* src = in.c_str();
	size_t src_len = in.size();

	// 目标字符串以及尺寸
	size_t dst_len = 2*src_len + 1; //c风格字符串需要一个结束符
	char* dst = new char[dst_len];  
	memset(dst,0,dst_len);

	// 转换
	size_t pReturnValue = 0;
	errno_t  error_info = wcstombs_s(
		&pReturnValue, //size_t *pReturnValue,
		dst,          //char *mbstr,
		dst_len,     //size_t sizeInBytes,
		src,           //const wchar_t *wcstr,
		_TRUNCATE //size_t count 
		);

	//
	string out = dst;
	delete[] dst;
	setlocale(LC_ALL, "C");
	return out;
}
//string to wstring
wstring s2ws(string& in)
{
	wstring out;
	setlocale(LC_ALL, "chs");

	const char* src = in.c_str();
	size_t dst_len = in.size() + 1;

	wchar_t* dst = new wchar_t[dst_len];
	memset(dst,0,dst_len);

	size_t return_num;
	mbstowcs_s(&return_num, dst, dst_len, src, _TRUNCATE);
	out = dst;

	setlocale(LC_ALL, "C");
	delete[] dst;
	return out;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值