- 浏览: 14763 次
- 性别:
- 来自: 大连
最新评论
1. char(表示8位ANSI),wchar_t(表示16位的Unicode字符,而且由于早期版本的编译器没有提供这个内建的数据类型,所以编译器只有在指定了/zc:wchar_t编译开关时才会定义这个数据类型,默认是指定的.)
说明:在编译器内建对wchar_t的支持之前,有一个C头文件定义了一个wchar_t数据类型,如下所示: typedef unsigned short wchar_t;
wchar_t c=L'A';//L表示在编译器该字符串应该编译为Unicode字符串.
2. 任何修改字符串的函数都存在一个安全隐患:如果目标字符串的缓冲区不够大,无法容纳所生成的字符串,就会导致内存中的数据被破坏.在应用程序中包含strSafe.h时,string.h也会包含进来.C运行库中现有的字符串处理函数(如_tcscpy宏后的那些函数)已经标记为废弃不用.如果使用了这些函数,编译器就会发出警告(注意:必须在包含其他所有文件之后才包含StrSafe.h),每个函数都有一个对应的新版本函数.前面的名称相同,但是在最后添加_s(例如:_tcscpy相对应的_tcscpy_s)
3. C运行时实际上允许提供自己的函数,这样一来,在他检测到了一个无效参数时就会调用此函数.然后在函数中记录失败,附上一个调试器,或者做其他我们想做的事情.为了启动这个功能,必须先定义好一个函数,原型如下:
void InvalidParameterHandler(PCTSTR expression,PCTSTR Function,
PCTSTR file,unsigned int line,uintptr_t/*pReserved*/)
其中:expression描述了C运行时实现代码中可能出现的函数调用失败.Function、flie、line分别描述了出现错误的函数名称、源代码文件和源代码行号.
然后调用_set_invalid_parameter_handler来注册这个处理程序.
最后在应用程序的开始调用_CrtSetReportMode(_CRT_ASSERT,0);从而禁止可能有C运行时触发的所有Assertion对话框.
4. C运行库新增了一些用户在执行字符串处理时提供更多控制的函数.其返回值为HRESULT. HRESULT值 描述 S_OK 成功,目标缓冲区中包含源字符串,并以\0结尾 STRSAFE_INVALID_PARAMETER 失败,将NULL传给了一个参数 STRSAFE_INSUFFICIENT_BUFFER 失败,指定目标缓冲区太小,无法容纳整个源字符串 _countof宏来获取字符数,sizeof获取字节数.
5. 我们如果要比较字符串是否相等或者进行排序.较好的函数是:CompareString(Ex)和CompareStringOrdinal.对于需要以符合用户语言习惯的方式向用户显示的字符串更是如此.
int CompareString( LCID locale,// 指定区域设置ID,使用GetThreadLocale()来获取
DWORD dwCmdFlags,//标志位,用于修改函数在比较字符串时采用的方法
PCTSTR pString1,//字符串1
int cch1,//字符串1的字符数
PCTSTR pString2,//字符串2
int cch2)//字符串2的个数
其中dwCmdFlags的取值有: 标志 含义 NORM_IGNORECASE LINGUISTIC_IGNORECASE 忽略大小写 NORM_IGNOREKANATYPE 不区分平假名和片假名字符 NORM_IGNORENONSPACE LINGUISTIC_IGNOREDIACRITIC 忽略non-spacing字符 NORM_IGNORESYMBOLS 忽略符号 NORM_IGNOREWIDTH 不区分同一字符串的单字节和双字节形式 SORT_STRINGSORT 将标点符号当作符号来处理 为了比较程序内部所用的字符串(如路径名、注册表项值、xml元素/属性等),应该使用CompareStringOrdinal(PCWSTR pString1,
int cchCount1,
PCWSTR pString2,
int cchCount2,
BOOL reCase)//由于这个函数执行的是码位比较,不考虑区域设置,所以速度很快.
以上两个函数的返回值:0:表示函数调用失败,
返回值为CSTR_LESS_THAN(定义为1)表明pString1小于pString2
返回值为CSTR_EQUAL(定义为2)表明pString1等于pString2
返回值为CSTR_GREATER_THAN(定义为3)表明pString1大于pString.
为了方便起见,如果函数成功,我们可以从返回值中减去2,从而使得结果与C运行库函数的结果值(-1,0,1)保持一致.
6. 应用程序字符处理遵循的原则如下:
■开始将文本字符串想象为字符的数组,而不是char或者字节的数组
■用通用数据类型(如TCHAR/PTSTR)来表示文本字符和字符串
■用明确的数据类型(如BYTE和PBYTE)来表示字节,字节指针和数据缓冲区
■用TEXT或_T宏来表示字面量字符和字符串,但为了保存一致性和更好的可读性,请避免两者混用.
■执行全局替换(用PTSTR替换PSTR)
■修改与字符串相关的计算.可以使用宏来避免犯错:
#define chmalloc(nCharactes) (TCHAR*) malloc(nCharacters * sizeof(TCHAR)) ■ 避免使用printf系列函数,尤其是不要用%s和%S字段类型来进行ANSI与Unicode字符串之间的相互转换.正确的做法是使用MultiByteToWideChar和WideCharToMultiByte函数.
■ Unicode和_UNICODE符号要么同时指定,要么都不指定. 7. 对于字符串处理函数,应该遵循以下基本准则:
■始终使用安全的字符串处理函数,比如后缀为_s的函数.或者使用前缀为StringCch的函数.后者主要在我们想明确控制截断的时候使用.
■不要使用不安全的C运行库字符串处理函数.
■利用/GS和/RTCs编译器标志来自动检测缓冲区溢出.
■不要使用Kernel32方法来进行字符串处理(例lstrcat)
■在应用程序的代码中,需要要比较两种字符串.其中程序字符串包含文件名,路径,XML元素/属性以及注册表项/值等.对于这些字符串,应使用CompareStringOrdinal来进行比较.用户字符串则一般要在用户界面上显示,对于这些字符串,应使用CompareString(Ex)来比较.
8. Unicode与ANSI字符串转换函数:
int MultiByteToWideChar(
UINT uCodePage,//标识了与多字节字符串关联的一个代码页值
DWORD dwFlags,//允许我们进行额外的控制,它会影响带变音符号.一般为0
PCSTR pMultiByteStr,//指定要转换的字符串
int cbMultiByte,//指定字符串的长度(字节数),如果为-1,则自动判断源字符串的长度
PWSTR pWideCharStr,//写入内存缓冲区
int cchWideChar);//缓冲区字符长度(字符数),如果传递0,则函数不会执行//转换,而是返回一个宽字符数,(包括终止字符'\0')只有当缓冲区能够容纳该数量的宽字符时转换才成功
一般的步骤如下: ① 调用MultiByteToWideChar为pWideCharStr参数传入NULL,为cchWideChar参数传入0,为cbMultiByte传入-1
② 分配一块足以容纳转化后Unicode字符的内存,大小是上次调用函数的返回值乘以sizeof(wchar_t)
③ 再次调用MultiByteToWideChar,这一次将缓冲区的地址作为pWideCharStr参数的值传入,将第一次得到的大小作为cchWideChar参数传入
④ 使用转换后的字符串
⑤ 释放Unicode字符串占用的内存块 UINTCodePage, // code page DWORDdwFlags, // performance and mapping flags LPCWSTRlpWideCharStr, // wide-character string intcchWideChar, // number of chars in string LPSTRlpMultiByteStr, // buffer for new string intcbMultiByte, // size of buffer LPCSTRlpDefaultChar, // default for unmappable chars LPBOOLlpUsedDefaultChar // set when default char used ); 其步骤与MultiByteToWideChar大致相同,只是在第二步不需要乘以sizeof(wchar_t)
注意:该函数的后两个参数,只有一个字符在uCodePage中指定代码页中没有对应的表示时才使用.在遇到一个不能转换的宽字符时,pDefaultChar用来指定字符(为NULL时,函数就会使用一个系统默认的字符,通常是?).
pfUsedDefaultChar指向一个布尔变量;在宽字符串中,如果至少有一个字符不能转换为对应的多字节的形式,则变量为TRUE,如果所有字符都能成功转换则设为FALSE(传入NULL).
发表评论
-
Python中正则表达式对中文的匹配问题
2012-07-06 09:45 717今天在用python匹配中文的时候出了问题,要么匹配不到, ... -
有限状态机实现正则表达式
2012-07-06 09:37 2040最近在写语法分析 ... -
jsp页面换行输出
2012-07-06 09:30 1146if(skins != null){ Iterator i ... -
js注册验证
2012-07-05 20:44 572function getFocus() //设置用户名文本 ... -
自定义通用查询组件
2012-07-03 13:42 6601、 设计通用查询窗口,严格的说这是一个目前只适合数据库 ... -
Flex 数据易犯错误: 常见误用和错误
2012-07-02 10:23 516在某些情形下,绑定操作似乎不能正常工作,此时你可能非常懊恼 ... -
Flex3 做界面与 VC交互
2012-07-02 10:22 670Flex3 代码 width="400&quo ... -
页面中嵌入FLEX应用-传参
2012-07-02 10:22 610项目需要在页面的某div中动态展现图表数据,最终选用FLE ... -
engine introduce
2012-07-02 09:43 476... -
Flex Spring整合包
2012-07-01 09:41 695Adobe Flex是一套创建富客户端应用(RIAs)的框 ... -
Flex 导出文件通用处理
2012-07-01 09:41 856本文 ... -
myeclipse6.5+flex 3 + tomcat6.0 + ds-console.war环境搭建
2012-07-01 09:41 371安装环境:myeclipse6 ... -
The architecture of Flex and Java applications two (Flex 和 Java 应用程序架构 2)
2012-07-01 09:41 508Flex and Java application ... -
Flex4+Spring3+Hibernate3+BlazeDS整合笔记
2012-07-01 09:41 555普通Java Web工程流行使用ssh框架,而当前台使用F ... -
PHP发送邮件乱码的具体解决方法
2012-06-30 17:57 835【转自】http://doc.chinaunix.net/ ... -
ASP.NET 使用alert弹出对话框后,CSS样式失效,字体变大的解决方法
2012-06-30 17:57 983ASP.NET 使用alert弹出对话框后,CSS样式 ... -
windows 7 下安装Oracle 9i 解决方法
2012-06-30 17:57 1247这里首先申明下,windows7下安装oracle9i 9 ... -
sql server 2000的一些问题解决方法
2012-06-30 17:57 567我机器上SQL Server 2000的sa密码因为长时间 ...
相关推荐
字符串的使用;本章导读;简单地说,序列是一块用来存放多个值的连续内存空间。 Python中常用的序列结构有字符串、列表、元组等。;序列中的所有元素都可以通过索引(下标)来获取 从左往右,第一个元素的索引为0,第二...
Java课件第二章补充字符串.ppt
第二章:IA-32处理器体系结构 第三章:汇编语言基础 第四章:数据传送,寻址和算术运算 第五章:过程 第六章:条件处理 第七章:整数算术指令 第八章:高级过程 第九章:字符串和数组 第十章;结构和宏 第十一章:32...
第二章 字符串处理和进制转换(C++)_codes.rar
内容包括: 第一章:开始shell程序 第二章:命令的输出和输入 第三章:分支和循环语句 第四章:参数解析和扩充 第五章:参数、变量和函数 第六章:字符串、文件和命令 第七章:正则式、sed和awk 第八章:调试和debug...
若相等,比较第二个字符和倒数第二字符,直到比较到字符串的中间字符为止,若都相等,则是回文,返回true。 Java语言程序设计(第3版)第06章-字符串全文共31页,当前为第6页。 6.1.1 字符串查找 Java语言程序设计(第3...
第二、找出组成字符串的字符个数和字符串的存储结构(比如数组)。 第三、对串的常规操作:求子串、插入字符、删除字符、置换字符、字符串的比较等。 第四、对串的一些比较复杂而有趣的操作,这里将在最后介绍一些...
第二章 字符串处理和进制转换(C++) 第2课 贝贝的图形(vhist)-2019-11-26 第二章 字符串处理和进制转换(C++) 第2课 贝贝的图形(vhist)-2019-11-26
第二章:Python初探 第三章:变量类型和运算符 第四章:列表,元组,字典和集合 第五章:Python字符串常用方法 第六章:Python流程控制 第七章:函数和lambda表达式 第八章:Python类和对象 第九章:Python异常处理...
第二章 字符串处理和进制转换(C++)_PDF(2020.06.10).rar
第二章:LabVIEW基本函数第三章:LabVIEW的程序运行结构 第四章:LabVIEW的数据结构及内存优化 第五章:字符串与文件存储 高级篇 第六章:属性节点、方法节点及引用 第七章:高级控件的运用 第八章:文本编程...
Swift中文教程第二章-2.3字符串和字符[定义].pdf
第二章:LabVIEW基本函数 第三章:LabVIEW的程序运行结构 第四章:LabVIEW的数据结构及内存优化 第五章:字符串与文件存储 高级篇 第六章:属性节点、方法节点及引用 第七章:高级控件的运用 第八章:文本编程与...
Kotlin 1.3 基础课程第二章 基础语法字符串模板及注释详解
ReactV 15.5.0 从入门到精通第二章 React语法基础字符串的常用方法
第二讲:delphi 过程函数 文件处理: 第三讲:字符串类型的应用以及for循环 第四讲:delphi几种常见控制语句的应用 界面制作: 第五讲:delphi界面制作:常见面板上的控件使用 第六讲:单选控件,复选控件,...
第二章: 编写Pascal代码 第三章: 类型、变量及常量 第四章: 用户自定义数据类型 第五章: 语句 第六章: 过程与函数 第七章: 字符串操作 第八章: 内存 第九章: Windows编程 第十章: Variant类型 第十一章: ...
第二章: 编写Pascal代码 第三章: 类型、变量及常量 第四章: 用户自定义数据类型 第五章: 语句 第六章: 过程与函数 第七章: 字符串操作 第八章: 内存 第九章: Windows编程 第十章: Variant类型 第十一章: ...
第二章:C++简单程序设计 第三章:函数 第四章:类与对象 第五章:C++程序的结构 第六章:数组、指针与字符串 第七章:继承与派生 第八章:多态性 第九章:群体类 第十章:群体数据的组织 第十一章:流类库...
• 第二章: 编写Pascal代码 • 第三章: 类型、变量及常量 • 第四章: 用户自定义数据类型 • 第五章: 语句 • 第六章: 过程与函数 • 第七章: 字符串操作 • 第八章: 内存 • 第九章: Windows编程 • 第十章...