2014-07-24
这是一年前的笔记。
操作系统默认字符集为utf-8。
示例1
例如:(文件编码为utf-8)
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
int main()
{
setlocale(LC_ALL,"zh_CN.utf8");
wchar_t *s=L"你好";
printf("%ls\n",s);
printf("%S\n",s);
printf("length:%ld\n",wcslen(s));
printf("%C\n",s[0]);
return 0;
}
编译输出:
你好
你好
length:2
你
示例2:
文件编码仍然为utf-8。
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
int main()
{
setlocale(LC_ALL,"zh_CN.GB18030");
wchar_t *s=L"你好";
printf("%ls\n",s);
printf("%S\n",s);
printf("length:%ld\n",wcslen(s));
printf("%C\n",s[0]);
return 0;
}
编译运行:
���
���
length:2
�
宽字符转换为多字符
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
#include <string.h>
int main()
{
setlocale(LC_ALL,"zh_CN.utf8");
wchar_t *s=L"你好";
char ch[100];
wcstombs(ch,s,100);
printf("%s\n",ch);
printf("length:%ld\n",strlen(ch));
printf("%c\n",ch[0]);
return 0;
}
编译运行:
你好
length:6
获取汉字的utf-8编码
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
int main()
{
setlocale(LC_ALL,"zh_CN.utf8");
wchar_t s[]=L"你好";
char ch[100];
wcstombs(ch,s,100);
printf("%s\n",ch);
printf("%x %x %x %x %x %x\n",(int)ch[0],ch[1],ch[2],ch[3],ch[4],ch[5]);
return 0;
}
编译运行结果为:
zsh >> gcc test.c
zsh >> ./a.out
你好
ffffffe4 ffffffbd ffffffa0 ffffffe5 ffffffa5 ffffffbd
在python交互环境中获取"你好"的utf8编码用来验证:
>>> u"你好".encode("utf-8")
'\xe4\xbd\xa0\xe5\xa5\xbd'
>>>
实际上下面这种方法也能获得(源文件是utf-8编码):
#include <stdio.h>
int main()
{
char *s="你好";
printf("%x %x %x %x %x %x\n",s[0],s[1],s[2],s[3],s[4],s[5]);
return 0;
}
多字符转换为宽字符
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
#include <string.h>
int main()
{
setlocale(LC_ALL,"zh_CN.utf8");
wchar_t s[100];
char *ch="你好";
mbstowcs(s,ch,100);
printf("%ls\n",s);
printf("length:%ld\n",wcslen(s));
printf("%C\n",s[0]);
return 0;
}
编译运行:
zsh >> gcc test.c
zsh >> ./a.out
你好
length:2
你
%ls
和%s
的区别很简单,%ls
意味着将对应的参数会被当作基于宽字符的字符串(wide chraracter string )看待,而%s
则意味着对应的参数会被当作普通字符串(multi-byte string)看待。
wprintf
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
#include <string.h>
int main()
{
setlocale(LC_ALL,"zh_CN.utf8");
wchar_t s[]=L"你好";
wprintf(L"---%ls\n",s);
//printf("%ls\n",s);
wprintf(L"---%ls\n",s);
return 0;
}
编译运行:
zsh >> gcc test.c
zsh >> ./a.out
---你好
---你好
有趣的现象
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
#include <string.h>
int main()
{
setlocale(LC_ALL,"zh_CN.utf8");
wchar_t s[]=L"你好";
wprintf(L"---%ls\n",s);
printf("%ls\n",s);
wprintf(L"---%ls\n",s);
return 0;
}
编译运行:
zsh >> gcc test.c
zsh >> ./a.out
---你好
---你好
再来个:
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
#include <string.h>
int main()
{
setlocale(LC_ALL,"zh_CN.utf8");
wchar_t s[]=L"你好";
printf("%ls\n",s);
wprintf(L"---%ls\n",s);
printf("%ls\n",s);
wprintf(L"---%ls\n",s);
return 0;
}
编译运行:
zsh >> gcc test.c
zsh >> ./a.out
你好
你好
还有其他的处理宽字符的函数,例如wsprintf,wscanf。