当前位置:   article > 正文

【字符集二】多字节字符vs宽字符

多字节字符

一、多字节字符(multibyte)

  • 定义:字符所用的字节个数是可变的,一个1字节字符后面可以跟着一个3字节字符。(比如中国象形文字)

备注:也有人称多字节字符为窄字符。但是《c++标准程序库》中称为多字节字符,我们沿用书中多字节的说法。

二、宽字符(Wide-Character)

  • 定义:字符所用的字节数(byte)恒定,与所表示的字符无关。
  • 典型的个数是2或4个字节。
  • 这和只使用1字节的表示法(例如ASCII),没有区别。

备注:也有文章中说,ASCII即无所谓宽字节和多字节。

三、使用范围

  • 多字节字符表示法比宽字符更紧凑,因此,多字节字符表示法常用来在程序外部存储数据;
  • 宽字符表示法比较容易处理固定大小的字符,所以通常在程序内部使用。

四、wchar_t

ISO C++使用wchar_t表示宽字符,在c++中wchar_t已被扶正为关键词。

已经验证:

  • windows下wchar_t是2字节,而在linux下是4字节。
  • 怀疑和系统有关。
  • g++ 在linux下编译,wchar_t为4字节。
  • vs在windows下编译运行,wchar_t为2字节。
  • WinGW在windows下使用g++编译,wchar_t为2字节。说明不是g++编译器的问题。
  • 曾经怀疑和字符集有关系,但是在winows下程序的运行字符集设置为gbk或者utf8,wchar_t都是2字节。(设置为utf32失败,原因未知)
  • 和cpu架构无关,因为windows和linux都是下x86架构
  • 国内说不清楚,翻墙去国外看看,其实也说的不是太明白,我们就把他当成变的吧,2字节或者4字节。
  • c++ 11已经增加了char16_t、char32_t、c++ 20增加了 char8_t,建议使用c++新定义的这些关键字,wchar_t后续我们会写一篇【字符集六】宽字符串和多字节字符互转串,之后就不再过多的探讨了。

五、字符转换

Class template codecvt用来在不同的字符编码方案之间进行转换
备注:未来再写

六、源文件字符集、运行字符集

这个区分的文章不是太多,但是我们要明白。

  • 源文件字符集:源文件存储采用的字符集。
    (eg.cpp文件的存储。如果按照《c++标准程序库》中多字节字符和宽字节字符的建议,源文件字符集应该采用多字节字符表示法较合理)
  • 运行字符集:程序运行过程中采用的字符集。
    (程序运行过程数据的输出等。如果按照《c++标准程序库》中多字节字符和宽字节字符的建议,运行字符集应该采用宽字符表示法较合理)

这个简要再多说2点,后面博客会详细介绍

  • 1、vs2017等建立的源文件采用的是Unicode字符集,utf-8的编码。
  • 2、源文件字符集和运行字符集一般不一定是一致的。(可以设置)
    后面文章再给大家介绍。

七、char、wchar_t

  • char用cout输出、wchar_t用wcout输出。
  • char
#include <iostream>
#include <locale>

void setLoc()
{
	std::locale::global(std::locale("chs"));
}

int main()
{
	using namespace std;

	//cout.imbue(locale("chs"));

	char ch1 = 'A';      // 正常
	char ch2 = '中';     // 错误,一个char不能完整存放一个汉字信息
	char ch3[4] = "中";  //前2个字节存放汉字'中',第3个字节存放字符串结束符\0 


	
	cout << ch1 <<endl;
	cout << ch2 << endl;
	cout << ch3 << endl << endl;


	setLoc();

	char ch4 = 'A';
	char ch5 = '中';
	char ch6[4] = "中";

	locale loc2;
	cout << ch4 << endl;
	cout << ch5 << endl;
	cout << ch6 << endl;

	system("pause");
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

输出:

在这里插入图片描述

  • wchar_t
#include <iostream>
#include <locale>
using namespace std;

void setLoc()
{
	std::locale::global(std::locale("chs"));
}

int main()
{
	

	//wcout.imbue(locale("chs"));  // 设置wcout
	//setlocale(LC_ALL, "chs");    // c语言设置locale为chs

	setLoc();
	wchar_t ch1 = L'A';      // L代表宽字符
	wchar_t ch2 = L'中';     // 一个汉字用一个wchar_t表示
	wchar_t ch3[4] = L"中";  //前两个字节(前一个wchar_t)存放汉字'中',最后两个字节(后一个wchar_t)存放字符串结束符\0 
	wcout << ch1 <<endl;
	wcout << ch2 << endl;
	wcout << ch3 << endl << endl;

 	system("pause");
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

输出

在这里插入图片描述

八、宽字符串、多字节字符串

#include <iostream>
#include <locale>
using namespace std;
int main()
{
	
	char * loc=setlocale(LC_ALL, "");    // 或者设置为chs,都可以输出,utf8 ,.65001都可以输出

	wchar_t ch1 = L'A';      // 正常
	wchar_t ch2 = L'中';     // 错误,一个char不能完整存放一个汉字信息
	wstring str = L"中";  //前两个字节(前一个wchar_t)存放汉字'中',最后两个字节(后一个wchar_t)存放字符串结束符\0 


	wcout << ch1 <<endl;
	wcout << ch2 << endl;
	wcout << str << endl << endl;

 	system("pause");
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

输出为
A

九、宽字符串和多字节字符互转串

参见:【字符集六】宽字符串和多字节字符互转串

参考:
1、C语言学习(十二)C语言中的字符(宽字符与窄字符)、从字符谈谈C语言的编码、转义字符

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/488557
推荐阅读
相关标签
  

闽ICP备14008679号