c++程序中文字符编码初探

前几天从一个PDF文档中复制一段代码到DEV-C++编辑器中时发生了一个奇怪的现象,代码中其他字符都正常复制了,但是其中∗(星号)这个字符在DEV-C++中变成了.(点),但是粘贴到记事本又是正常的,这搞得我很晕。于是在网上恶补了一些字符编码的知识,基本搞懂了中文字符在计算机中的编码处理方法,下面以windows系统c++程序处理中文字符的方法来举例说明。

首先介绍一下字符编码的基础知识。

ascii:单字节,表示0到127共128个字符,最高位为0

GBK:双字节,国标扩展码

utf-16:双字节,unicode

utf-8:1到6个字节,unicode,汉字为3个字节

// encode.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include 
#include 
#include 
#include  

#pragma execution_character_set("utf-8")   //指示编译器生成utf-8格式代码

using namespace std;

int main(int argc, char *argv[])
{
	setlocale(LC_ALL, ".65001");	//告诉系统以utf-8编码解析字符和字符串
	
	char ca1[] = "中";
	cout << ca1 << endl;
	for (int i=0; i < strlen(ca1); i++)
	{
		printf("i:%d byte: %x\n", i, (unsigned char)ca1[i]);    //输出的是字符的utf-8编码
	}

	wchar_t wca1[] = L"中";
	wcout << endl;
	wcout << wca1 << endl;	
	for (int i = 0; i < wcslen(wca1); i++)
	{
		printf("i:%d byte: %x\n", i, wca1[i]);	//输出的是字符的unicode编码
	}

	setlocale(LC_ALL, ".936");  	//告诉系统以GBK编码解析字符和字符串,标准输入不支持utf-8编码。
				                    //如果不setlocale,ca2能得到GBK编码,但输出为空,wca2则两者皆失败

	char ca2[10] = {};
	cout << endl;
	cin >> ca2;
	for (int i=0; i < strlen(ca2); i++)
	{
		printf("i:%d byte: %x\n", i,(unsigned char)ca2[i]); //输出的是字符的GBK编码
	}
	cout << ca2<> wca2;
	for (int i = 0; i < wcslen(wca2); i++)
	{
		printf("i:%d byte: %x\n", i, wca2[i]);	//输出的是字符的unicode编码
	}
	wcout << wca2;

	return 0;
}

程序输出:

c++程序中文字符编码初探_第1张图片

 

可以看到,在utf-8编码的程序中,以char表示的字符确实是utf-8编码的,但是以wchar_t表示的字符则内码是unicode码。以char存储的标准输入字符是以GBK编码的,但是以wchar_t存储的标准输入字符则内码是unicode码。如果在标准输入以前不setlocale为936(GBK)的话,标准输入会失败,这表明标准输入不支持utf-8编码格式读取字符。

开始我把函数setlocale的作用搞错了,原来我以为它是用来设定编码的,其实不是的,它只是用来通知系统用什么编码来解析字符和字符串。有了它,我们就可以覆盖控制台默认的代码页。如果执行程序的编码和setlocale指定的编码或系统的编码不一致,则中文字符会显示乱码。

回到开始的问题,∗(星号)不是*(指针星号),这个字符DEV-C++编辑器不支持,所以显示不出来。关于粘贴,Microsoft Docs有一段说明:

The format of extended characters on the Windows clipboard is specific to application locale settings. Cutting and pasting these characters into your code from another application may introduce unexpected character encodings. This can result in parsing errors with no visible cause in your code. We recommend that you set your source file encoding to a Unicode codepage before pasting extended characters. 

翻译一下:windows粘贴板上的扩展字符的格式是特定于应用区域设置的。从另一个应用剪切和粘贴字符到你自己的代码可能引入不希望的字符编码。这可能导致在你的代码里发生解析错误,并且原因是不可见的。我们建议你在粘贴扩展字符前先设置好你的源文件编码为unicode代码页。

另外原来有一个困惑,输入法是如何把汉字传送给编辑器的,现在我明白了,它是先把汉字字符传给操作系统,然后由系统传给编辑器,不是直接传送的。

你可能感兴趣的:(windows系统,c++,汉字编码)