zepor

二进制旅程


宽字符

<p>[TOC]</p> <h1>🌓wchar_t数据类型</h1> <p>学过C语言的都知道,char类型只占据1个字节,但是在windows开发的时候用到更多的是宽字符(Unicode),所以在不改变char数据类型的情况下,重新创造了一个新的16位数据类型 <code>wchar_t</code> ,它在几个表头文件包括WCHAR.H中都有定义为</p> <pre><code class="language-cpp">typedef unsigned short wchar_t;</code></pre> <p>所以wchar_t数据类型和无符号短整数类型相同</p> <p>要定义一个宽字符变量,可以如下</p> <pre><code class="language-cpp">wchar_t c = 'A';</code></pre> <p>变量c是一个双字节值0x0041,表示Unicode中的字母A</p> <p>还可以定义指向宽字符串的指针</p> <pre><code class="language-cpp">wchar_t *p = L"hello";</code></pre> <p>在引号前面的大写字母L代表long,这告诉编译器该字符串按宽字符保存</p> <h1>🌓wchar_t字符串长度</h1> <p>在C语言中,获取字符串长度可以使用strlen函数来获取字符串长度,但是对于wchar_t不可以使用strlen,因为包含“\x00”,直接截断了,所以针对于宽字符有专门函数</p> <pre><code class="language-cpp">size_t __cdecl wcslen(const wchar_t*);</code></pre> <p>获取宽字符串长度可以如下</p> <pre><code class="language-cpp">iLength = wcslen(str);</code></pre> <h1>🌓char和wchar_t</h1> <p>有时候我们既想按ASCII编译,又想按Unicode编译,这样源码就需要按照两种方式来编写,最好的解决方法是维护一个可以按两种编码编译的单一源码,一个办法是使用TCHAR.H头文件,TCHAR.H为需要字符串参数的函数提供了一系列替代名,但该文件不是ANSI C标准的一部分,所以定义的每个函数和宏定义前面都有一个底线,例如_tprintf,这些名称为通用函数名称,它既可以指向Unicode版函数也可以指向非Unicode版函数</p> <p>如果文件里定义了 <code>_UNICODE</code> 标识符,同时包含TCHAR.H头文件,那么_tcslen就定义为</p> <pre><code class="language-cpp">#define _tcslen wcslen</code></pre> <p>没有定义该标识符的话,_tcslen定义为</p> <pre><code class="language-cpp">#define _tcslen strlen</code></pre> <p>其他函数同理,同时还定义了TCHAR数据类型来解决两种字符数据形态问题,如果定义了 <code>_UNICODE</code> 则TCHAR定义为</p> <pre><code class="language-cpp">typedef wchar_t TCHAR;</code></pre> <p><code>_UNICODE</code> 未定义则TCHAR定义为</p> <pre><code class="language-cpp">typedef char TCHAR;</code></pre> <p>接下来就是字符串中的L问题,如果定义了 <code>_UNICODE</code> ,那么一个宏 <code>__T</code> 定义为</p> <pre><code class="language-cpp">#define __T(x) L##x</code></pre> <p>这里一对井号称为粘贴符号,它将L添加到宏参数上</p> <p>如果没有定义 <code>_UNICODE</code> ,则宏 <code>__T</code> 定义为</p> <pre><code class="language-cpp">#define __T(x) x</code></pre> <p>此外还有两个宏和 <code>__T</code> 定义相同</p> <pre><code class="language-cpp">#define _T(x) __T(x) #define _TEXT(x) __T(x)</code></pre>

页面列表

ITEM_HTML