GCC编译选项:
-finput-charset:输入字符集设置(需要和源文件编码一致),告诉编译器以什么样的编码形式读入源文件中的字符串,
-fexec-charset:执行字符集设置(需要设置为当前运行环境支持的编码),告诉编译器在内存中以什么样的编码形式保存字符串
-fwide-exec-charset:宽字符执行编码(在windows下应设置为utf-16LE),告诉编译器在内存中以什么样的编码形式保存宽字符串。
以windows为例,详细介绍下c程序在执行过程中,编码方式转换的流程:
运行环境:
系统:windows系统
gcc编译选项:
-finput-charset = utf-8
-fexec-charset = gbk
-fwide-exec-charset = utf-16LE
源代码的文本文件所使用字符集:utf-8编码
编码转换流程:
char *test = "超银河传说";//由于源字符集(input-charset)为utf-8,执行字符集(exec-charset)为gbk,所以引号中的字符串将以utf-8的编码形式被操作系统识别(强调源字符集应与源代码文本文件字符集一致的重要性,否则会被操作系统误识别从而产生乱码),然后以gbk编码的形式存入内存(注意:在源字符集到执行字符集转换的过程中,gcc会通过内部编码进行过度转换,内部编码也为utf-8,所以转换流程为:源字符集(input-charset) →gcc内部处理编码(为utf-8)→执行字符集(exec-charset))。
printf("%s",test); //向终端输出字符串,编码为当前内存中的编码也就是执行字符集的编码:gbk。如果终端支持当前编码格式,则正确输出,否则出现乱码。(所以强调执行字符集应设定为程序运行环境支持的字符集,不然会出现乱码)
setlocale(LC_ALL, ""); //设置地域信息
wchar_t *test2 = L"超银河传说\n"//由于源字符集(input-charset)为utf-8,宽字符执行字符集(wide-exec-charset)为utf16-LE,所以引号中的字符串将以utf-8的编码形式被操作系统识别(再次强调源字符集应与源代码文本文件字符集一致的重要性),然后以utf-16LE的编码形式存入内存(转换过程依然通过gcc内部编码(utf-8)进行过度转换)。
wprintf(L"%s",test2);//首先调用 wcstombs()将utf-16LE()转换为当前local设定的编码,如果没有设定则为经典c local(只支持c语法字符),不能打印中文。需要通过setlocal设置区域信息
#include "stdio.h"
#include <locale>
int main(int argc, char *argv[])
{
char *test = "超银河传说\n"; //程序按照utf-8编码读入字符串,并按照gbk的编码方式保存至内存
printf("%s",test); //直接打印输出内存中以gbk编码保存的的字符串
setlocale(LC_ALL, ""); //设置地域信息
wchar_t *test2 = L"超银河传说\n"; //程序按照utf-8编码读入字符串,并按照utf-16LE编码方式保存至内存
wprintf(L"%s",tailuo); //将utf16-LE编码转换为地域设置的编码
}
char