C/C++宽窄字符转换与输出(多种方法)
宽字符
C语言中的宽字符
-------------------------------------------------------
https://blog.csdn.net/ken2232/article/details/130316198
QString::toWCharArray 与 宽字符路径、空格 (测试OK)(***)
=========================
C/C++宽窄字符转换与输出(多种方法)
文章目录
C语言宽字符输出和转换
==> 学习汇总(持续更新)
==> 从零搭建后端基础设施系列(一)-- 背景介绍
宽字符
Unicode
宽字符有很多种,Unicode只 是宽字符编码的一种实现,每个字符用 16位 表示。
Unicode的产生是为了解决许多8位无法标识的东西。
ASCII
这是世界上流行的编码,每个字符用 7位 表示。但是这套编码不能表示一些其他国家的字符,可以说这套编码是为美国设计的。
C语言的宽字符是基于 wchar_t 数据类型的。这个数据类型被定义在多个头文件中,包括 WCHAR.H
typedef unsigned short wchar_t;
所以 wchar_t 数据类型和一个无符号整型一样,都是 16位 宽。
可以这样定义一个包含单个宽字符的变量
wchar_t c = 'A' ;
也可以这样定义:
wchar_t c = L'A' ; //但这通常是不需要的。
变量 c 是一个 2 byte 的值0x0041,这是Unicode中字母A的代表。它在内存中的存储是按照高位在后,低位在前存储的。
所以在内存中是这样,0x41,0x00。
可以这样定义一个已初始化的指向宽字符串的指针:
wchar_t *p = L"Hello!";
注意:大写字母 L 紧接着左引号。这向编译器表明这个字符串将用宽字符存储,也就是说每个字符 2 byte。
这个字符串一共 14 byte,因为字符串结尾需要加 0 。
指针变量 p 需要 4 byte的存储空间,因为在汇编里 cs:ip 表示代码执行的指针。cs : 段位移 ip : 偏移地址。
宽字符库函数
大家都知道 char *pc = "Hello!"; iLength = strlen(pc); iLength = 6
那么 wchar_t *pw = L"Hello!"; iLength = strlen(pw); iLength = ?
此时编译的话编译器会发出警告,意思是strlen函数在被定义是为接收一个指向char的指针,
但这里收到的是一个指向无符号短整型的指针。但仍可以运行。 但 iLength =1 这是为什么呢?
因为这些字符串数据是这样存储在内存中的 48 00 65 00 6c 00 6F 00 21 00
strlen函数仍试图找字符串的长度,计算第一个字节作为字符,但然后认为第二个字节 0 为字符串的结尾。所以长度为 1 。
因此对于宽字符的数据处理也引入了专门的库函数。
宽字符版本的strlen函数被称为 wcslen("string"),并定义在STRING.H 和 WCHAR.H 中。
在介绍使用之前,先来介绍下面两个数据类型: CHAR WCHAR
在 WINNT.H 中定义了:
typedef char CHAR; 用来定义 8位 的字符
typedef wchar_t WCHAR; 用来定义 16位 的字符
当然其中也定义了字符指针:
这些都是 8位 字符串指针 指每次指针移动偏移 8位
typedef CHAR * PCHAR,* LPCH,* NPSTR, * PSTR;
typedef CONST CHAR * LPCCH, * PCCH, * LPCSTR, * PCSTR;
这里的 PCHAR,LPCH,NPSTR,PSTR 都是CHAR * 的别名,以后定义一个指针就可以直接用别名了。
例如 :CHAR *P 和 PCHAR P 是同一个意思,懂了吧
也有 16位 的字符串指针 指每次指针移动偏移 16 位
typedef WCHAR *PWCHAR,*LPWCH, *PWCH, *NWPSTR, *LPWSTR, *PWSTR;
typedef CONST WCHAR * LPCWCH, * PCWCH, * LPCWSTR, * PCWSTR;
另外,前缀 N 和 L 分别是表示"近"(near),和"远"(long),指的是 16位 Windows系统中的两种大小不同的指针
不过在win32中near,和long指针没有区别,所以不必管它。
那么如何使用同一个函数名来实现不同的功能呢?
在包含头文件 TCHAR.H 的情况下,举个例子:如果一个命名为_UNICODE的标识符被定义了,那么就实现处理宽字符串的功能,
否则就仍是处理单字节字符的字符串。
#ifdef UNICODE typedef WCHAR TCHAR, *PTCHAR ; typedef LPWSTR LPTCH, PTCH, PTSTR, LPTSTR ; typedef LPCWSTR LPCTSTR ; #else typedef char TCHAR, *PTCHAR ; typedef LPSTR LPTCH, PTCH, PTSTR, LPTSTR ; typedef LPCSTR LPCTSTR ; #endif 同时用来选择字符处理函数,例如WINUSER.H中: #ifdef UNICODE #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif
这 样,我们只用一种类型(比如TCHAR)和一组函数(比如MessageBox)就方便地可以处理两种编码的程序,
而不用去条件判断应该用char还是 wchar_t,
应该用MessageBoxA还是MessageBoxW。这些细节Windows.h等头文件中已经为我们考虑了,
我们要做的只是在需要用Unicode时定义两个符号。
另外提醒一下:
_UNICODE 是让 C 函数使用 unicode
UNICODE 是让 API 使用 unicode
========================================
https://blog.csdn.net/Last_Impression/article/details/103042865
C语言中的宽字符
在C语言中,使用wchar.h
头文件中的wchar_t
来定义宽字符,例如:
wchar_t ch = 'A';
wchar_t 被定义为typedef unsigned short wchar_t
,和一个无符号整型一样,占用两个字节。
如果定义宽字符串,需要加前缀L
,例如:
wchar_t *str = L"C语言中文网";
L
是必须要加的,并且与字符串之间不能有空格,只有这样编译器才知道每个字符占用两个字节。宽字符示例: