您的位置:首页 > 其它

学习笔记之字符和字符串处理

2012-12-18 18:57 288 查看
在编程中使用的字符和字符串形式归结于两种:ANSI和Unicode。由于Unicode字符字符串在国际上更通用,以及有利于COM和.NET Frameword进行互操作,更好的防范了缓冲区溢出的问题,所以编程中极力推荐使用Unicode字符和字符串。

ANSI中的字符和字符串为一个字节的char类型,而Unicode中的字符和字符串为两个字节的wchar_t内建数据类型。他们的常见使用方式为:

char c = 'A'; char szBuffer[100] = "A String";

wchar_t c = L'A'; wchar_t szBuffer[100] = L"A String";

在WinNT.h中,有大量方便的数据类型以供我们使用:

typedef char CHAR;

typedef wchar_t WCHAR;

typedef CHAR *PCHAR;

typedef CHAR *PSTR;

typedef CONST CHAR *PCSTR;

typedef WCHAR *PWCHAR;

typedef CONST WCHAR *PWCSTR;

为了在使用ANSI或Unicode字符/字符串时能够通过编译,WinNt.h中还有如下的宏:

#ifdef UNICODE

typedef WCHAR TCHAR, *PTCHAR, PTSTR;

typedef CONST WCHAR *PCTSTR;

#define __TEXT(quote) L##quote

#else

typedef CHAR TCHAR, *PTCHAR, PTSTR;

typedef CONST CHAR *PCTSTR;

#define __TEXT(quote) quote

#endif

#define TEXT(quote) __TEXT(quote)

使用上面的宏,无论使用ANSI还是Unicode字符都能通过编译。如:

TCHAR c = TEXT('A');

TCHAR szBuffer[100] = TEXT("A String");

当一个windows函数的参数列表中有字符串,则该函数通常有两个版本,一个是ANSI版本(即在函数名最后加一个A),一个是Unicode版本(即在函数名最后加一个W),如CreateWindowExW,CreateWindowExA。但也有一些例外情况,如windowsAPI的一些函数(WinExec和OpenFile)存在的目的就是为了向后兼容16位的windows程序,因为后者只支持ANSI字符串。在开发新程序的时候,应避免使用这些函数,调用新的函数(CreateProcess和CreateFile)来代替。随着Microsoft的发展,开始倾向于某些函数只有Unicode版本(ReadDirectoryChangesW
和 CreateProcessWithLogonW),Microsoft将COM从16位windows移植到Win32时,做出了一个重要决策,将所有需要字符串作为参数的COM接口方法都只接受Unicode字符串,因为COM一般用于不同的组件彼此间“对话”,Unicode是传递字符串的理想选择。

C运行库中的字符串函数和安全字符串函数(前面名字相同,后面加了一个_s):

_tcslen,测试字符串的长度

_tcscat,连接字符串

_tcscpy,复制字符串

所有的安全字符串函数的首要任务是验证传给它们的参数值,检查项目包括:指针不为NULL,整数在有效范围内,枚举值是有效的,缓冲区足以容纳结果数据。如果检查有一项失败,函数会设置线程的c运行时变量errno。然后返回一个errono_t值来指示成功或失败。然而函数并不实际返回(自己指定的函数除外),如果是调试版本,系统会弹出一个不友好的对话框,然后终止应用程序进行。如果是发行版本,则直接终止程序运行。

c运行时允许我们提供自己的函数,在它检测到参数无效时,就会调用我们的函数。在这个函数中我们可以记录失败信息并提示,附上一个调试器或做其他事情。要启用此功能:

首先要定义好一个函数: void InvalidParameterHandler(PCTSTR expression, PCTSTR function, PCTSTR file, unsigned int line, uintptr_t /*pReserved*/);

expression描述c运行时实现代码中可能出现的函数调用失败的原因,但是它的显示方式并不友好。

function描述出错的函数名

file描述出错的源代码文件

line描述出错的源代码行号

其次调用_set_invalid_parameter_handler来注册这个处理程序。

最后要在应用程序开头的地方调用_CrtSetReportMode(_CRT_ASSERT, 0);

从而禁止可能由C运行时触发的所有调试中断对话框。

字符串的更多控制(可截断或填充):

StringCchCat、StringCchCatEx,连接字符串

StringCchCopy、StringCchCopyEx 复制字符串

StringCchPrintf、StringCchPrintfEx 按指定格式填充字符串

CompareString、CompareStringEx比较一般字符串

CompareStringOrdinal 比较程序内部所用的字符串(如路径名,注册表项/值,XML元素/属性等)使用码位比较,不考虑区域设置,只支持Unicode字符串

sizeof 与 _countof的区别:

sizeof 查询目标所占的字节数

_countof查询目标的元素个数

字符串转换:

WideCharToMultiByte,将Unicode字符串转换为ANSI字符串

MultiByteToWideChar,将ANSI字符串转换为Unicode字符串

转换步骤:

先调用一次转换函数来获取转换所需要的空间大小

然后构建空间

最后再调用转换函数转换字符串

释放内存

检测文件的字符串版本:

BOOL IsTextUnicode(CONST PVOID pvBuffer, int cb, PINT pResult);

pvBuffer要测试的缓冲区地址

cb指定pvBuffer缓冲区的字节数

pResult指定希望函数进行哪些测试,为NULL表示执行每一项测试
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: