字符串有好几种不同的类型,新手一开始学的一定是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的函数就是使用操作系统默认的语言设置。
VC++:wcslen以及一系列函数的含义
最新推荐文章于 2024-04-22 20:23:47 发布