汉字编码问题(OJ 2h奋战血泪)

发布时间 2023-04-05 11:24:00作者: ZZQ323

image

永远想不到汉字的utf-8 gcc 编码其实是三个字符,我是在云IDE发现的.....

#include<bits/stdc++.h> 

using namespace std;


//A>K>Q>J>>10>9>...>3>2
struct Card{
	char name[10];
	int color;
	int number;
	void change(){
		if( strstr(name,"大王") ){
			color=11;
		}else if( strstr(name,"小王") ){
			color=10;
		}else if( strstr(name,"黑桃") ){
			color=4;
		}else if( strstr(name,"红桃") ){
			color=3;
		}else if( strstr(name,"梅花") ){
			color=2;
		}else if( strstr(name,"方块") ){
			color=1;
		}
        // printf("%s",name);
        // printf("::%d\n",strlen(name) );
        // for(int i=0;i<strlen(name);i++){
        //     printf("%d ",name[i]);
        // }
        // puts("");
		switch (name[6]){
		case 'A':{
			number=23;
			break;
		}
		case 'K':{
			number=22;
			break;
		}
		case 'Q':{
			number=21;
			break;
		}
        case 'J':{
			number=20;
			break;
		}
		default:{
			if(name[7]=='0')
				number=10;
			else 
				number=name[6]-'0';
			break;
		}
		}
	}
	bool operator<(const Card&x)const{
		if(color!=x.color)
		    return color>x.color;
		else 
			return number>x.number;
	}
}var[1000];

signed main(void)
{								
	int  T;
	scanf("%d",&T);
	while(T--){
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++){
			scanf("%s",var[i].name);
			var[i].change();
		}
		sort(var+1,var+1+n);
		for(int i=1;i<=n;i++){
			printf(" %s"+(i==1),var[i].name);
		}
		printf("\n");
	}
	return 0;
}

汉字编码问题

编码就是把什么东西当作什么的问题,计算机善于处理数字,任何自然状态下不能表示为数字的东西,都是难以直接处理的;若我们可以把那些东西都用数字表示出来,那就可以被计算机处理,享受计算机的带来的便利;
字符串在计算机内部主要是以末尾有\0char数组形式储存;这个东西发源西方,对于中文,处理char的编译器(gcc,clang)就不认识了,本质上是编译器采取的utf-8编码和GBK编码(策略)不能把汉字处理成一个字面量;所以出现了unicode编码去用一个'字符'(多个字节)去代表中文;
C语言内部的Unicode就是wchar_t;
在实验的过程中可以发现汉字输入进去之后是不止一个字符的,但也不一定是两个字符,而且其char保存的数值还是负数,大概是当初ASCII码编写的是时候没有留位置或者是需要当作unsigned char去处理;

数据类型 编码 size_t
clang gcc
char GBK 8 两个 8 两个
char utf-8 (BOM)8两个/12三个个 12三个
wchar_t Unicode 一个 一个

Unicode

Unicode编码不是char类型自然拥有的编码,他需要用新的数据类型,在C语言内部就是wchar_t,那么也有相应的处理这个的函数,egwprintf() , wscanf
转换成Unicode:
clang: utf-8(有bom) -> gbk -> Unicode
gcc: utf-8(默认)->Unicode

#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main()
{
    wchar_t a [] = L"ABCD";
    wchar_t b [] = L"\x41\x42\x43\x44";

    setlocale(LC_ALL, "");
    wprintf(L"a:%ls b:%ls", a, b);
    return 0;
}

printf()是根据格式控制符来解释内存中的内容的,所以,当我们用 char*wchar_t * 时,格式控制就很重要了,不然一个 wchar_t* 直接作为 char * 来解释或翻过来解释,结果你可以想得到的,对吧;