C++语法查漏补缺(第五期)(基础IO库与字符编码)
IO类正如字面上说的是标准库对于输入(Input),输出(Output)的相关定义,在平常的使用中我们已经了解了大部分的IO库设施了。
1.平常经常使用的IO库设施
istream(输入流) 类型,提供输入操作
ostream(输出流) 类型,提供输出操作
cin,一个istream对象,从标准输入读取数据
cout,一个ostream对象,像标准输出写入数据
cerr,一个ostream对象,通常用于输出程序错误的信息,写入到标准错误
>>运算符,用来从一个istream对象读取输入数据
<<运算符,用来从一个ostream对象写入输出数据
getline函数,从一个给定的istream读取一行数据,存入一个给定的string对象中
2.字符编码
我自己看到这章的时候注意到了宽字符这个东西,稍微深挖了一下,感觉有必要记录一下
以下内容参考这篇博客https://blog.csdn.net/leeta521/article/details/119378886
最开始得时候为了把英语字符与二进制位之间得关系做了统一规定,于是制定了ASCII码,用七位二进制码表示了128个字符。
随着计算机在全球得普及,由于字符编码不同,计算机在不同国家之间得交流变得十分困难,经常出现乱码,为了解除地域限制,人们迫切得希望有一个统一得规则,对所有国家地区得字符进行编码,于是Unicode就出现了
1.Unicode
Unicode是国际标准字符集,它将世界各种语言得每个字符定义一个唯一得编码,以满足跨语言、款平台得文本信息转换
注意,这里说得Unicode是字符集,而不是字符编码,字符集仅仅规定了字符的编码,但是并没有规定在计算机中的存储规则
接下来要说的Utf-8、Utf-16、Utf-32才是真正的字符编码规则。
2.Utf-32
UTF-32 是固定长度的编码,始终占用 4 个字节,足以容纳所有的 Unicode 字符,所以直接存储 Unicode 编号即可,不需要任何编码转换。浪费了空间,提高了效率。
3.Utf-8
Utf-32对于英文使用者简直就是灾难,本来只需要一个字节来存储的,硬是翻了4倍,于是发明了Utf-8这种可变大小的编码方式,表现为
0xxxxxxx:单字节编码形式,这和 ASCII 编码完全一样,因此 UTF-8 是兼容 ASCII 的;
110xxxxx 10xxxxxx:双字节编码形式;
1110xxxx 10xxxxxx 10xxxxxx:三字节编码形式;
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx:四字节编码形式。
4.Utf-16
介于Utf-8与Utf-32之间,既可以固定长度,同时也可变,使用 2 个或者 4 个字节来存储
对于 Unicode 编号范围在 0 ~ FFFF 之间的字符,UTF-16 使用两个字节存储,并且直接存储 Unicode 编号,不用进行编码转换,这跟 UTF-32 非常类似。
对于 Unicode 编号范围在 10000~10FFFF 之间的字符,UTF-16 使用四个字节存储,具体来说就是:将字符编号的所有比特位分成两部分,较高的一些比特位用一个值介于 D800~DBFF 之间的双字节存储,较低的一些比特位(剩下的比特位)用一个值介于 DC00~DFFF 之间的双字节存储。
3.char数组为何能存储汉字
那么问题来了,众所周知char类型一般来说是一个字节,按照Unicode或者任何中文字符集区区8bit一个字节啥都存不了,凭啥char数组能够存储汉字
其实在windows操作系统下,中文默认是采用gbk字符集,每个字符占16bit,char数组用两个char类型表示一个中文字
4.宽字符
C++程序需要处理的字符集可能无法用一个8位的字节表示,于是好心的C++给你准备了宽字符wchar_t类型,在windows系统中汉字用GBK编码所以“汉”这个字的GBK编码为47802,来实测一下
#include<iostream>
using namespace std;
int main()
{
wchar_t a = '汉';
cout << a;
}
输出结果:
可以看到完全没有问题。
5.char16_t和char32_t
这是C++11为了兼顾Unicode编码而定义的,这里只提一下用法,等我具体用到的时候再来深挖,接下来的代码只保证能在vs中没问题。
#include<iostream>
using namespace std;
int main()
{
char32_t a = L'汉';
cout << a;
}
输出结果:
不加L还是gbk编码,加上L就是Unicode编码,“汉”的Unicode编码就是27721