您的位置:首页 > 编程语言

Windows核心编程 第二章 字符和字符串处理

2013-05-12 21:46 447 查看
1. Windows Vista中每个Unicode字符都是用UTF-16编码。

2. Unicode 前0x7F个字符兼容ASCII编码。

UTF-8 :将一些字符编码为1个字节,一些字符编码为2个字节,一些字符编码为3个字节,一些字符编码为4个字节。

UTF-16 :将每个字符编码为2个字节(16位)。

UTF-32 :将每个字符都编码为4个字节, 较少用, 一般在应用程序内部使用。

3. C语言中的字符表示:

char : 8位 ASCII 编码

wchar_t : 16位 Unicode (UTF-16)编码

4. 使用UTF-16字符串的时候应在字符串前面加上大写字母L。表明使用一个unicode字符串。

5. Windows编程中 源代码使用的数据类型应坚持使用Windows数据类型,增加代码的可读性。

6. Windows中提供两个编码版本的函数。以W结尾的是UNICODE编码函数,以A结尾的是ANSI编码的函数

如:

CreateWindowExW

CreateWindowExA

7. Windows内部使用的是UNICODE函数,因此开发时应该尽量使用Unicode 函数以提高应用程序的效率,避免Windows在内部还要将ANSI 函数转为UNICODE函数。

8. MS的C库的ANSI和Unicode版本之间没有互相调用关系的,没有编码转换开销。

9. 宽字符函数:_tcscpy,_tcscat,_tcslen。

10. UNICODE宏是Windows API使用的,而MS的C库中,对于非标准的东西用_前缀区分,所以_UNICODE宏是MS的CRT库函数所使用。 使用C\C++编程中,要确保要么UNICODE 和 _UNICODE都define或是全部没define。

11. 使用StrSafe.h里面的安全字符处理函数。StrSafe库中提供 Cch和 Cb两种函数, Cch传入的是字符数,可用_countof取得,Cb表示的是字符串的字节数。 在源串过短时,<StrSafe.h>的函数处理方式是截断而<TChar.h>的函数则使用断言。

12. 自定义C运行库函数传入参数无效的异常处理方法:

(1) 定义一个 InvalidParameterHandler 函数,用于注册异常抛出函数。格式如下:

void InvalidParameterHandler(PCTSTR expression,

PCTSTR function,

PCTSTR file,

unsigned int line,

uintptr_t);

(2) 调用_set_invalid_parameter_handler 注册异常函数

(3) 使用_CrtSetReportMode 关系VS自带的debug dialog 。

示例代码:

/****************************************************************************************
*    自定义C运行库函数传入参数无效的异常处理方法:                                                *
*    (1) 定义一个 InvalidParameterHandler 函数,用于注册异常抛出函数。格式如下:                *
*        void InvalidParameterHandler(PCTSTR expression,                                    *
*            PCTSTR function,                                                            *
*            PCTSTR file,                                                                *
*            unsigned int line,                                                            *
*            uintptr_t);                                                                    *
*    (2) 调用_set_invalid_parameter_handler 注册异常函数                                    *
*    (3) 使用_CrtSetReportMode 关系VS自带的debug dialog 。                                    *
*****************************************************************************************/

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <crtdbg.h>
#include <tchar.h>
#include <windows.h>
#include <strsafe.h>
using namespace std;

void InvalidParameterHandler(PCTSTR expression, PCTSTR function, PCTSTR file, unsigned int line, uintptr_t )
{
wcout << "自定义的C运行库异常处理 : " << endl;
wcout << expression << endl;        //哪句表达式发生异常
wcout << function << endl;            //哪一个函数发生异常
wcout << file << endl;                //在哪个文件发生异常
wcout << line << endl;                //第几行抛出异常
throw 0;    //抛出异常
}

int main (void)
{
_CrtSetReportMode(_CRT_ASSERT, 0);
_set_invalid_parameter_handler(InvalidParameterHandler);

try{

TCHAR szbefore[5] = L"BBBB";
TCHAR szAfter[5] = L"AAAA";
TCHAR buf[10] = {0};
errno_t ret = _tcscpy_s(buf, _countof(buf), L"0123456789");
}
catch(int err)
{
if ( 0 == err )
cout << "接受到 InvalidParameterHandler 抛出的异常!" << endl;
}

return 0;
}


13. 使用Shlwapi.h的字符串处理函数, 如:需要比较向用户显示字符串的比较函数使用 CompareString , 比较程序内部使用的字符串(如路径名、注册表项/值等)应使用CompareStringOrdinal

14. 使用MultiByteToWideChar 和 WideCharToMultiByte 可以转换字符编码。其中,在宽字节转多字节的时候,如果有Unicode字符在多字节编码中没有对应项,那宽字节会被替换成参数lpDefaultChar,并且lpUsedDefaultChar 会被标记为TRUE。当用这两个函数计算结果串的大小时,返回的是字符数。

15. IsTextUnicode 可以检测字符编码是属于UNICODE还是ASCII。

16.关闭VS对不安全的字符串函数警告或报错的方法: 在源程序最顶端加上宏定义 #define _CRT_SECURE_NO_DEPRECATE 即可关闭字符串不安全函数的警告或报错。

Unicode 和 ANSI 编码相互转换示例代码:

#include <windows.h>
#include <iostream>
using namespace std;

// Unicode编码转为ASCII 编码
int UnicodeToAnsi(wchar_t *str_wide, char *str_ansi, unsigned int cbsize)
{
return WideCharToMultiByte(CP_ACP, 0, str_wide, -1, str_ansi, cbsize, NULL, NULL);
}

// ASCII转为Unicode 编码
int AnsiToUnicode (char *str_ansi, wchar_t *str_wide, unsigned int chcount)
{
return MultiByteToWideChar(CP_ACP, 0, str_ansi, -1, str_wide, chcount);
}

int main (void)
{
// code conversion
char str[50] = {0};
wchar_t wide[] = L"人生长恨水厂东";

cout << UnicodeToAnsi(wide, str, 50) << endl;
cout << str << endl;

char ansi[] = "人生长恨水厂东" ;
wchar_t p[50];

AnsiToUnicode(ansi, p, _countof(p));
MessageBox(NULL, p, p, 0);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: