咦,好久没更新博客了。我都在干嘛呢。嗯这是个好问题。最近(其实已经是两个月以前的事情了)看DX的时候遇到了一些字符串转换的问题,感觉比较麻烦,不如一次查清楚分享出来啦(博主真是个好人)。

首先看看维基百科关于C string handling的词条说在C语言里的string分两种:一种叫string(也可以叫byte string)是以char为单位构成的,另一种叫wide string,是以wchar_t为单位构成的,两者都以'\0'结尾。我们的讨论就围绕这两种string以及它们之间的转换来进行。

char和wchar_t

char是8位字符类型,就是说呢,一个字符有8位,所以最多就能表示2^8=256种不同的字符啦。而wchar_t类型根据不同的C/C++库有不同规定,一般是16位或者32位的。

之所以会有wchar_t类型的存在,是因为很多语言不像英语一样字母那么少啊,256种根本表现不过来啊摔。综上所述,在要用到各种字母很多的奇奇怪怪语言(比如中文、日文)的时候,就要用到wchar_t了。顺便吐槽下日语虽然只有50音,但是人家也有汉字啊汉字啊!

string和wide string

有了构成的两种元素,我们就可以开聊string和wide string了。

string呢就是string,wide string就是wstring。它们在C++标准里的定义分别是:

typedef basic_string\ string;
typedef basic_string\ wstring;

所以其实就只有charwchar_t的区别。那么写写看?

++
1
2
3
4
string str = "Hello world!";
wstring wstr = L"Hello world!";
//cout << str << endl;
//wcout << wstr << endl;

看起来就是所有函数前都加个w就可以啦。注意在表示宽字符串常量的时候,前面要加上个大写的L。’Introduction to 3D Game Programming with DirectX 9.0’这本书中的样例里都没加这个,不知道是不是写这个书的时候年代比较久远,那些接口大约还没有宽字符串的支持?那个时候大约只要用string就可以了吧。

然后既然有两种字符串,当然是可以转换哒!你问我怎么换?当然是用库函数了哼!

转换

++
1
int swprintf (wchar_t* ws, size_t len, const wchar_t* format, ...);

ws是一个指向用于存放结果宽字符串的buffer的指针
len是buffer的最大值(len不算最后那个空字符的长度)
format就是我们常在printf里写的那个格式啦
后面还可以有一些附加的参数,就类似于printf后面那些参数啦,详细可参考这里
返回值是一个int类型,表示string中字符的个数

给个例子吧

++
1
2
3
4
wchar_t buffer[100];
int no = 1;
swprintf(buffer, 100, L"Hello World %d!\n", no);
wcout << buffer << endl;

wsprintf

虽然这个跟swprintf长得很像,但人家是Windows的API啦,在这里.aspx)可以查到。这个函数的意思是:

Writes formatted data to the specified buffer.

跟宽字符串没什么关系啦。而且人家还说:

Note Do not use. Consider using one of the following functions instead: StringCbPrintf, StringCbPrintfEx, StringCchPrintf, or StringCchPrintfEx. See Security Considerations.

嗯,不要用。

再说一点

关于wchar_t的内容在这里都可以找到。

最后鞠躬,谢幕。(๑•̀ω•́๑)

参考文献

[1] 维基百科词条-C string handling
[2] http://www.cplusplus.com/reference/cwchar/