字符串字面量怎么被编码成字节的
什么是字符串?C#里的 string?C++里的char* ? 字符串的本质是什么?字符串不过是一个特殊的数据字节包装 带有编码信息,特别是C++的 更原始 更便于我们想清楚这个底层,其实其他的已经迎刃而解了。首先我们无论如何确定一个东西 那就是交换的东西是字节码 ,说白了 也就是C++ 里的char [ ] 也就是char *,在我不管你编码的情况下 我新建VC++项目 在代码里这样写:
1 char str1[] = "中a"; 2 printf("%s\r\n", str1;
能不能输出东西?能不能输出中文 当然能,那这个str1 字节码到底是什么字节码,只要我们把这个搞明白就可以了。一切未知的恐惧源于不明白。我们先调试C++代码 取到字节码,然后编写下面这两句C#代码:
1 byte[] bts2 = new byte[] { 0xd6, 0xd0, 0x61 }; 2 Console.WriteLine(Encoding.GetEncoding("gb2312".GetString(bts2;
正常输出了C++代码里的中文 由此可见C++里默认代码到字节 的字面量转换 就是gb2312,就这样而已。就这样而已,真的就这么点东西,事情不要歪呀歪的想想复杂了。你看C++里是char [ ] 还不像C#的string经过包装的 更便于你想明白这个过程。不是说C++有std库么 不是有string 么 还没讲呢,C++这门语言呢又好又不好 设计特点是暴露的细节多 各个细节你都可以自己控制 让会用的人知道自己在做什么,但是也有些坑,其实string 就是char[] 的变种而已。你看C++里 在你琢磨不透的情况下悄然在你不知情编码的情况下转换成了字节码,C#的string 封装的 不会给你这个机会 有明确的Encoding库调用指定编码。
窄字符和宽字符,怎么个宽法
1 byte[] bts3 = new byte[] { 0x2d,0x4e, 0x61,0x00, }; 2 Console.WriteLine(Encoding.Unicode.GetString(bts3;
关于UTF-8
1 void UnicodeToUtf8(const wchar_t* unicode,char utf82[],int * lenout 2 { 3 int len; 4 len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, NULL, 0, NULL, NULL; 5 char szUtf82[50] = { 0 }; 6 *lenout = len; 7 WideCharToMultiByte(CP_UTF8, 0, unicode, -1, utf82, len, NULL, NULL; 8 9 }
关于VC++项目属性里的设置字符集
当选用“使用Unicode字符集”时,调用函数MessageBox,实际使用的是MessageBoxW,MessageBoxW关于字符串的入参类型是LPCWSTR,使用MessageBox时,字符串前需加L::MessageBox(NULL, L"这是一个测试程序!", L"Title", MB_OK;
最后,一些测试的大杂烩代码:
1 // ConsoleApplication1.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include <iostream> 6 #include "h2.h" 7 #include "FqTabData.h" 8 #include "test1.h" 9 10 #include <windows.h> 11 #include <string> 12 #include <iomanip> 13 #include <type_traits> 14 15 using namespace std; 16 17 18 //引用的使用方式 19 void test1(int &r{ 20 r = r+1; 21 } 22 23 void UnicodeToUtf8(const wchar_t* unicode,char utf82[],int * lenout 24 { 25 int len; 26 len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, NULL, 0, NULL, NULL; 27 char szUtf82[50] = { 0 }; 28 *lenout = len; 29 WideCharToMultiByte(CP_UTF8, 0, unicode, -1, utf82, len, NULL, NULL; 30 31 } 32 int _tmain(int argc, _TCHAR* argv[] 33 { 34 35 setlocale(LC_ALL, "";//注意控制台输出要先加上这句哈要不然无法输出中文 36 wchar_t wstr2[] = L"中a"; 37 wprintf(L"%ls\r\n", wstr2; 38 39 char str1[] = "中ab"; 40 printf("%s\r\n", str1; 41 return 0; 42 //关于c++里的编码问题 43 // 并非 不在在项目属性里设置编码字符集 为Unicode 就不能显示中文 44 //char str11[] = "中a"; printf("%s", str11; 45 //这段代码照样显示中文,中a被编译器编成3个元素存在str11 里+\0结尾 46 //当选择“使用Unicode字符集”时,编译器会增加宏定义——UNICODE;而选择“使用多字节字符集”时,编译器则不会增加宏定义——UNICODE。 47 //https://blog.csdn.net/huashuolin001/article/details/95620424 48 //当选用“使用Unicode字符集”时,调用函数MessageBox,实际使用的是MessageBoxW,MessageBoxW关于字符串的入参类型是LPCWSTR, 49 //使用MessageBox时,字符串前需加L 50 //::MessageBox(NULL, L"这是一个测试程序!", L"Title", MB_OK; 51 52 //关于这个L,等同于_T("" Tchar 这些玩意儿他们都有同等意义 53 //可以傻瓜的理解 L 本身就是搞一个宽字符型 字符串,每个字符占2字节 54 //wchar_t ws[] = L"国家"; 55 //设置为Unicode 就意味着宽字符 就意味着字符串 要加L 56 //就像前面的 好多函数接口有两种版本 MessageBoxA MessageBoxW, 57 //MessageBoxW就意味着你要传一个宽字符数组进去 也就是 wchar_t 或者L"dd" 58 59 //注意多字节字符集是一个很容易让人费解的玩意儿, 60 //我们说 utf-8是 一种Unicode的落地编码 61 //编程里都是用 Unicode 不管项目设没设置Unicode字符集 wchar_t ws[] = L"国家"; 得到的都是宽字符串 62 //但是编程代码里 没有utf-8 这一说法 utf-8是变长的 也就是多字节 他是一种编码落地 63 //你想想你整个变长 别人接口怎么写,怎么达到在让你用变长省内存的同时 识别你的有效字符 64 //如果数组里存utf-8 你想想 别人要以字节数读字符 半个的时候怎么搞 65 //这跟gdi图像处理是同一个道理 jpg png 各种是落地格式都可以读进来 但是到内存都是bmp 66 67 //还有不论哪种printf 或者其他接口 都不支持所谓的utf-8的参数 也没这种接口可言 68 //https://zhuanlan.zhihu.com/p/23190549 69 //前几天在微博上受到了@Belleve给我的启发,于是简单地实现了几个在 Windows 70 //下接受 UTF - 8 参数的 printf 系列函数。大致思路是判断当前 stdout / stderr 71 //是否为控制台,如果是控制台则将参数转为 UTF - 16 后调用 wprintf 输出,否则不转换直接调用 printf。 72 73 //L 是一个很微妙的,称之为转换为宽字符的字面量 什么叫字面量 根据你当前编程环境 以及源代码编码 转换成对应的字节 74 //L"发" 字面量 你细品 75 setlocale(LC_ALL, ""; 76 77 78 79 80 printf("--------------------"; 81 //wchar_t wc = L'破'; 82 std::wstring wstr = L"破a的"; 83 std::cout << wstr.size( << std::endl; 84 //utf-8 只是流行,事实上utf-8 一个汉字要占3字节 而utf-16一个汉字一字节 85 /*wchar_t wstr2[] = L"破晓S"; 86 wprintf(L"%ls", wstr2;*/ 87 printf("--------------------//"; 88 89 char utf82[50] = { 0 }; 90 int len = 0; 91 UnicodeToUtf8(wstr2, utf82, &len; 92 //char* str222 = UnicodeToUtf8(wstr2; 93 //printf("%S", str222; 94 //printf("aaa"; 95 return 0; 96 // 97 //c++ 中指针的变种 引用的使用方式 98 printf("aaa\r\n"; 99 100 int a = 123; 101 int& b = a; 102 a = 456; 103 printf("%d \r\n", b; 104 105 test1(b; 106 printf("%d \r\n", b; 107 108 int c = 345; 109 test1(c; 110 printf("%d \r\n", c; 111 return 0; 112 }