Windows 编 程中的字符串

(1)在win32编程中,如何使用string类型

#include <string>
using namespace std;

LPTSTR    lpCmdLine = L"hello world";string cmd = lpCmdLine;

(2)字符格式基础:

  传统的ansi字符在C语言中用char数据类型表示(1字节)。在源代码中声明一个字符串,则编译器会转换为由8位char数据类型构成的一个数组(以"/0"结尾)

  char c=‘a‘;//一个8位的字符

  char szbuffer[100]="a string";//含有99个8位字符和1个8位结束符(/0)的数组

  微软的c/c++编译器为unicode定义了一个内建的数据结构,wchar_t,它表示一个16位的unicode(UTF-16)字符。

  wchar_t c=L‘a‘;//一个16位的字符

  wchar_t szbuffer[100]=L"a string";//含有99个16位字符和1个16位结束符(/0)的数组

  字符串比较函数:

if (_stricmp("hello world", cmd.c_str()) == 0){
}

  lstrcmp 对两个字符串进行区分大小写的比较
  lstrcmpi 对两个字符串进行不区分大小写的比较 

(3)C运行库中的安全字符串处理函数

  通常,修改字符串的函数都存在一个安全隐患,即目标字符串的缓冲不够大,则会导致内存中的数据被破坏。

例如:

  WCHAR szbuffer[3]=L"";

  wcscpy(szbuffer,L"abc");

  以上的例子是以0结尾的,需要szbuffer[4]才可以容纳。但编译时并不会有任何报错或警告。

  针对以上问题,我们必须使用“安全字符串处理函数”,这一类的函数以_s结尾(secure之意),我们来看一下这类函数的原型.

    PTSTR _tcscpy(PTSTR strDestination,PCTSTR strSource);

    errno_t _tcscpy_s(PTSTR strDestination,size_t numberOfCharacters,PCTSTR strSource);

    PTSTR _tcscat(PTSTR strDestination,PCTSTR strSource);

    errno_t  _tcscat_s(PTSTR strDestination,size_t numberOfCharacters,PCTSTR strSource);

    可以看到,在将一个缓冲区作为目标缓冲区时,必须提供这个缓冲区的大小(可容纳的字符个数),通过调用_countof宏计算出来。

  这个缓冲区大小参数的主要任务就是验证缓冲区是否足以容纳结果数据.

    现在,我们调用这些安全函数的时候,就可以检查返回的errno_t值。只有返回S_OK值,才表明函数调用成功。其他的值可以参照errno.h中的定义。

  来看一个例子:

  TCHAR szbuffer[3]=L"";

  _tcscpy_s(szbuffer,_countof(szbuffer),_T("abc"));

  执行完后, szbuffer的第一个字符被设置为‘/0‘,而其他所有字节全部被设置为0xfd(填充符)。

(4)c运行库增加的函数:控制如何截断字符串

    这类函数具有两个版本,对应ansi和unicode。

HRESULT StringCchCat( LPTSTR pszDest,size_t cchDest,LPCTSTR pszSrc);

HRESULT StringCchCatEx( LPTSTR pszDest,size_t cchDest, LPCTSTR pszSrc,LPTSTR *ppszDestEnd,size_t *pcchRemaining,DWORD dwFlags);

HRESULT StringCchCopy( LPTSTR pszDest,size_t cchDest, LPCTSTR pszSrc);

HRESULT StringCchCopyEx(LPTSTR pszDest,size_t cchDest, LPCTSTR pszSrc, LPTSTR *ppszDestEnd,size_t *pcchRemaining,DWORD dwFlags);

  可以看出,在所有方法的名称中,都含有一个“Cch”,这表示count of characters,即字符个数。通常使用_countof宏获得。

  另外还有一些函数含有“cb”,这表示函数要求用字节数来指定大小。通常使用sizeof()获得。

  这些函数返回HRESULT,具体的值

S_OK 成功。目标缓冲区中包含源字符串,并以/0终止
STRSAFE_E_INVALID_PARAMETER 失败。将NULL传给了一个参数
STRSAFE_E_INSUFFICIENT_BUFFER 失败。指定的目标缓冲区太小,无法容纳整个源字符串

不同于安全字符串处理函数,这类函数运行时,当缓冲区太小,则会执行截断。

(5)windows字符串处理函数

  在shlwapi.h定义了大量好用的字符串函数,可以用来对操作系统有关的数值进行格式化操作。

  例如,比较两个字符串是否相等:对于这样的需求可以使用CompareString(Ex)或者CompareStringOrdinal。

    CompareString(Ex)一般用于向用户显示的字符串。

    CompareStringOrdinal一般用于比较程序内部的字符串,如路径名,注册表项值等。

  CompareString(Ex)的处理速度相对于CompareStringOrdinal较慢。

  这两个函数的返回0,则表示调用失败;

    返回1(CSTR_LESS_THAN)表明string1小于string2;

    返回2(CSTR_GREATER_THAN)表明string1大于string2.

(6)推荐的字符处理方式

  1、使用通用数据类型和宏,如TCHAR和_T

  2、将字符串想象成字符的数组,而非char或字节的数组。

  3、与字符串有关的计算需修改。尤其要搞清楚很多的函数要求传递的是字符数还是字节数,如是前者,则用_countof()获取;如是后者,则用(字符数*sizeof(字符类型))获取。

  4、避免使用printf系列函数转换ansi和unicode。正确的做法是使用MultiByteToWideChar或WideCharToMultiByte。

  5、始终使用安全的字符串处理函数,_s或stringcch,如要控制截断,则使用后者。

  6、如果一个缓冲区处理函数的参数中不包括目标缓冲区的长度,那么避免使用。

  7、比较字符串时,使用CompareStringOrdina和CompareString(Ex)。前者速度快,适合处理程序内部的字符串;后者用于处理UI的字符串,因为它是以区域设置来适当排序,速度较慢。

 

  转自http://blog.csdn.net/shentao17792/article/details/5314312

时间: 2024-08-01 22:41:48

Windows 编 程中的字符串的相关文章

在C#中子线程如何操作主线程中窗体上控件

在C#中子线程如何操作主线程中窗体上控件 在C#中,直接在子线程中对窗体上的控件操作是会出现异常,这是由于子线程和运行窗体的线程是不同的空间,因此想要在子线程来操作窗体上的控件,是不可能简单的通过控件对象名来操作,但不是说不能进行操作,微软提供了Invoke的方法,其作用就是让子线程告诉窗体线程来完成相应的控件操作. 要实现该功能,基本思路如下: 把想对另一线程中的控件实施的操作放到一个函数中,然后使用delegate代理那个函数,并且在那个函数中加入一个判断,用 InvokeRequired

关于Delphi中的字符串的详细分析

关于Delphi中的字符串的详细分析 只是浅浅的解析下,让大家可以快速的理解字符串. 其中的所有代码均在Delphi7下测试通过. Delphi 4,5,6,7中有字符串类型包括了: 短字符串(Short String) 长字符串(Long String) 宽字符串(Wide String) 零结尾字符串(Null-Terminated String).PChar和字符数组 1.短字符串(Short String) 固 定长度,最大字符数个数为255,短字符串也成为长度字节(Length-byt

Python中Unicode字符串

Python中Unicode字符串 字符串还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111=十进制255),0 - 255被用来表示大小写英文字母.数字和一些符号,这个编码表被称为ASCII编码,比如大写字母 A 的编码是65,小写字母 z 的编码是122. 如果要表示中文,显然一个字节是不够的,至少需要两个字节,而且

关于Delphi中的字符串的浅析(瓢虫大作,里面有内存错误的举例)

关于Delphi中的字符串的浅析 只是浅浅的解析下,让大家可以快速的理解字符串. 其中的所有代码均在Delphi7下测试通过. Delphi 4,5,6,7中有字符串类型包括了: 短字符串(Short String) 长字符串(Long String) 宽字符串(Wide String) 零结尾字符串(Null-Terminated String).PChar和字符数组 1.短字符串(Short String) 固定长度,最大字符数个数为255,短字符串也成为长度字节(Length-byte)字

sql语句中截取字符串

今天在开发过程中因为要用到合并单元格,在程序里实现了以后,查出来的数据太长,都把格式撑大了,后来想想可以在sql语句查询的时候就截取,就去网上找了一下,挺好用,就转了过来: 合并单元格: /// <summary>    /// 合并GridView中某列相同信息的行(单元格)    /// </summary>    /// <param name="GridView1">GridView</param>    /// <para

【转】BAT批处理中的字符串处理详解(字符串截取)

下面对这些功能一一进行讲解. 1.截取字符串 截取字符串可以说是字符串处理功能中最常用的一个子功能了,能够实现截取字符串中的特定位置的一个或多个字符.举例说明其基本功能: @echo off set ifo=abcdefghijklmnopqrstuvwxyz0123456789 echo 原字符串(第二行为各字符的序号): echo %ifo% echo 123456789012345678901234567890123456 echo 截取前5个字符: echo %ifo:~0,5% ech

利用ASP.NET加密和解密Web.config中连接字符串

介绍 这篇文章我将介绍如何利用ASP.NET来加密和解密Web.config中连接字符串 背景描述 在以前的博客中,我写了许多关于介绍 Asp.net, Gridview, SQL Server, Ajax, JavaScript等的文章.大多数情况下,我都把数据库的连接字符串放在了web.config中.其中包含许多敏感信息,包括连接数据库的用户名密码等.然而我们在web.config和machine.config中以纯文本的方式保存密码安全吗? 如果我们的程序只是部署在内部服务器中,这应该没

在.NET Windows Form Application中统一处理未处理的异常总结

在Windows Form Application中,异常若最终得不到处理,则会触发AppDomain.CurrentDomain.UnhandledException事件进行以进行最终的异常记录(使用此事件无法避免应用程序的终结).在此事件被触发之前,分以下情况可决定是否将异常继续传播. 主线程 使用Application.SetUnhandledExceptionMode(bool)方法预先设置处理模式: 若为UnhandledExceptionMode.ThrowException,则表示

在windows右键菜单中加入自己的程序 [转载]

原文链接: http://blog.csdn.net/marklr/article/details/4006356 在windows右键菜单中加入自己的程序 标签: windowsattributes扩展commandshell文档 2009-03-20 08:44 3369人阅读 评论(1) 收藏 举报  分类: BCB(12)  修改右键菜单应该在注册表中,具体的说,是在HKEY_CLASSES_ROOT根键下(这里可是右键菜单中所有命令的根源哦!).展开该根键,其下的子键主要有两种:扩展名