分享

VC 函数含义及编码转换

 一世的追逐 2012-05-24
字符串有好几种不同的类型,新手一开始学的一定是char,这种是最基础的字符串,用ASCII码来表示英文,这个叫做ANSI编码。现在新写程序都应当使用宽字符,类型是wchar_t,一个wchar_t占两个字节,不管英文还是中文,这种编码是一种Unicode编码,Unicode编码的程序即使拿到其他语言的系统上运行也能正确显示,前提是那个系统安装了中文字体。还有一种是MBCS,翻译成中文就是多字节字符串,一个字符有多个字节组成,不一定是2字节也可以多余两字节,GB2312,UTF8等都属此类。
编译器是不能自动转换char和wchar_t的,因为他们之间的转换必须要指定代码页。
微软提供了一系列的函数来对应操作这些字符串,你只要在msdn搜一个strlen,他下面会列出比如wstrlen,w开头的用来操作wchar_t,mb开通的用来操作MBCS等。
值得一提的是一组_t开头的,这是一种“自适应”的函数,在Visual Studio的工程选项里面可以选择应用程序编码使用Unicode还是普通的,那么这个_t就会自动适应这个选项,比如_tcslen在选项为Unicode的时候自动执行wstrlen,在选项为ANSI编码的时候执行strlen。
再说一下Windows API有关字符串类型的定义,常见的有这么几个
#define  LPSTR    char*
#define  LPCSTR  const char*
#define  LPTSTR  TCHAR*
#define  LPCTSTR  const TCHAR*
#define  LPWSTR   wchar_t*
#define  LPCWSTR  const wchar_t*
你仔细看一下就找到了规律,LP是指针,微软的传统,STR表示字符串,C表示const,T表示TCHAR,W表示wchar_t。
最后说一下TCHAR,TCHAR和前面说的_tcslen有一样的作用,他是这么定义的
#ifdef _UNICODE
#define TCHAR   wchar_t
#else
#define  TCHAR char
#endif
也就是根据编译器的自动适应。
最后很重要的一点是你在程序里面怎么表示char和wchar_t的字符串。
最熟悉的就是拿引号包括在字符串两边,这样表示这个字符串是char类型的:
LPCSTR sz = "Some characters";
这个是不能付给需要wchar_t的地方的,比如你写wprintf(sz)就是错的,编译器会报错不能从const char*转成const wchar_t*。写宽字符字符串必须在引号前加一个L,如
LPCWSTR szw = L"Wide characters";
这样wprintf(szw)就正确了。
为了自适应TCHAR的需要,微软有定义了一个宏,_T,这个宏包括在字符串的变
LPCTSTR tsz = _T("adaptive characters");
这样的字符串会根据编译器的选项自动加L或者不加。

然后那些函数里面的n,比如strncpy还有类似的后面带_s的,strcpy_s,这又是完全另外一个问题。原因是原始的C语言库比如strcpy很容易导致缓冲区溢出,你很容易写出这样的语句
char sz[5];
strcpy(sz, "something to copy");
这个语句完全通过编译,但是他有严重的问题,sz的长度不足以复制那整个字符串,而strcpy却不知道,因此它就会试图去修改超过缓冲区的内容,导致缓冲区溢出,缓冲区溢出是很广泛的漏洞,原始的C语言库无法避免的这问题,有时候你接受用户的输入,你没法知道用户会输入多少数据。
因为现在有了strncpy, strcpy_s以及比如scanf_s, gets_s等几乎所有的标准库函数都带了一个或多个变形的版本,这些版本基本就只多了一个参数,就是你给这个函数的缓冲区大小。比如刚才的例子:
strcpy_s(sz, 5, "ssdfsfdsfsf");
这个代码在Debug版本运行的时候就会跳出Runtime Error告诉你Buffer to small,在Release版本不会跳错,但是它会截断你要复制的字符串到缓冲区的大小,保证不会发生缓冲区溢出。
新编写严肃的程序都应当使用安全版本的函数,s可以理解是safety的缩写。现在微软的编译器在你使用strcpy这样不安全的函数的时候会提出警告。

带l的函数就是可以设置一个字符语言的区域,没有l的函数就是使用操作系统默认的语言设置。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多