mbs字符串(char*)与Unicode字符串(wchar_t*)的转换.md

2024-06-17 01:08

本文主要是介绍mbs字符串(char*)与Unicode字符串(wchar_t*)的转换.md,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、C语言库函数

(1)setlocale()

功能:配置地域化信息;在输出Unicode字符串时会用到,在使用wcstombs函数时也会用到。下面英文描述中的用粗体字标出的函数都会用到该函数
头文件:< locale.h>;
函数原型:

char *setlocale (int category, const char * locale);

函数参数:

  • category 表示对本地化的某项内容进行设置,可取如下值:

    • LC_ALL 包括下面的全部选项都要;
    • LC_COLLATE 配置字符串比较;
      The strcoll, _stricoll, wcscoll, _wcsicoll, strxfrm, _strncoll, _strnicoll, _wcsncoll, _wcsnicoll, and wcsxfrm functions.
    • C_CTYPE 配置字符类别及转换,例如全变大写 strtoupper();
      The character-handling functions (except isdigit, isxdigit, mbstowcs, and mbtowc, which are unaffected).
    • LC_MONETARY 配置金融货币;
      Monetary-formatting information returned by the localeconv function.
    • LC_NUMERIC 配置小数点后的位数;
      Decimal-point character for the formatted output routines (such as printf), for the data-conversion routines, and for the non-monetary formatting information returned by localeconv. In addition to the decimal-point character, LC_NUMERIC also sets the thousands separator and the grouping control string returned by localeconv.
    • LC_TIME 配置时间日期格式,与 strftime() 合用。
      The strftime and wcsftime functions.
  • locale 表示本地域代号:
    如果为NULL,则返回当前的locale名称(一般为C);如果非空,则根据category和locale进行设置,如果成功,则返回新的locale名称(地域名称),如果失败,则返回 NULL。

注意:可能刚开始对category参数有些不理解,category参数是指定全局变量locale会影响到的范围,也就是说如果我指定了LC_COLLATE参数,那么该函数的set只在字符串比较时会起作用

代码示例:

int main()
{wchar_t wstr[] = L"Hello 中国";//locale传 "" 空字符串用来返回当前环境的local名char* LocaleName = setlocale(LC_ALL, "");//locale传 "chs" 表示设置locale为简体中文setlocale(LC_ALL, "chs");//输出"Hello 中国",如果没有setlocale配置区域信息的话wprintf是无法正常输出中文字符的wprintf(wstr);//将区域信息设置回初始值if (0 == setlocale(LC_ALL, LocaleName)){printf("配置出错\r\n");return 0;}return 0;
}
(2)wcstombs()

功能:将宽字符编码字符串转换成多字节编码字符串
头文件: < stdlib.h>
函数原型:

//普通版本
size_t wcstombs(char *mbstr,const wchar_t *wcstr,size_t count
);
//安全版本
errno_t  wcstombs_s(size_t * _PtNumOfCharConverted, char * _Dst, size_t _DstSizeInBytes, const wchar_t * _Src, size_t _MaxCountInBytes
);
//带区域设置的安全版本
errno_t _wcstombs_s_l(size_t *pReturnValue,char *mbstr,size_t sizeInBytes,const wchar_t *wcstr,size_t count,_locale_t locale
);

函数参数
_PtNumOfCharConverted:指向转换后的字符串的长度加上结束符(单位字节);
_Dst:指向转换后的字符串首地址;
_DstSizeInBytes:目的地址最大字节空间(单位字节);
_Src:源宽字符串首地址;
_MaxCountInBytes:最多可存入多字节字符串缓冲最的字节数,用于裁剪转换后的字符串。
返回值:成功返回0, 失败则返回失败代码。

代码示例:
没有写,和mbstowcs的差不多,写在下面了。

(3)mbstowcs()

函数功能:将多字节编码字符串转换成宽字符编码字符串
头文件:< stdlib.h>
函数原型:

//普通版本
size_t mbstowcs(wchar_t *wcstr,const char *mbstr,size_t count
);
//安全版本
errno_t __cdecl mbstowcs_s(size_t * _PtNumOfCharConverted, wchar_t * _DstBuf, size_t _SizeInWords, const char * _SrcBuf, size_t _MaxCount 
);
//带区域参数的安全版本
errno_t _mbstowcs_s_l(size_t *pReturnValue,wchar_t *wcstr,size_t sizeInWords,const char *mbstr,size_t count,_locale_t locale
);

参数说明:
_PtNumOfCharConverted:指向转换后的字符串的长度加上结束符(单位wchar_t),;
_DstBuf:指向转换后的字符串首地址;
_SizeInWords:目的地址最大字空间大小(单位wchar_t);
_SrcBuf:源多字节字符串首地址;
_MaxCount:最多可存入宽字符串缓冲中的字符个数,用于裁剪转换后的宽字符串。

返回值:成功返回0, 失败则返回失败代码。

代码示例

  • 普通版本

    int main()
    {
    char str[] = "Hello 中国";
    //直接把宽度sizeof(str) * 2是有些内存资源浪费的,但也只能这样了,MultiByteToWideChar是可以直接计算缓冲区大小的
    wchar_t wstr[sizeof(str) * 2];
    //使用mbstowcs转换字符串
    mbstowcs(wstr,str,sizeof(str));
    //这里使用C++中的输出方式输出
    wcout.imbue(locale("chs"));
    wcout << wstr << endl;
    return 0;
    }
  • 安全版本

    int main()
    {
    size_t convertedChars = 0;
    char str[] = "Hello 中国";
    //直接把宽度sizeof(str) * 2是有些内存资源浪费的,但也只能这样了
    wchar_t wstr[sizeof(str) * 2];
    //设置区域信息为简体中文
    setlocale(LC_ALL, "chs");
    //使用mbstowcs转换字符串
    mbstowcs_s(&convertedChars, wstr, str, sizeof(str));//convertedChars是_Out参数,用于记录转换成功的字符
    //这里使用C++中的输出方式输出
    wcout.imbue(locale("chs"));
    wcout << wstr << endl;return 0;
    }
  • 带区域参数的安全版本

    int main()
    {
    size_t convertedChars = 0;
    char str[] = "Hello 中国";
    //直接把宽度sizeof(str) * 2是有些内存资源浪费的,但也只能这样了
    wchar_t wstr[sizeof(str) * 2];
    //使用_mbstowcs_s_l转换字符串
    _mbstowcs_s_l(&convertedChars, wstr, sizeof(str)*2, str, sizeof(str), _create_locale(LC_ALL,"chs"));//convertedChars是_Out参数,用于记录转换成功的字符
    //这里使用C++中的输出方式输出
    wcout.imbue(locale("chs"));
    wcout << wstr << endl;
    return 0;
    }

二、Windows函数

(1)WideCharToMultiByte()

函数功能:将宽字符串转换成多字节字符串
头文件:< windows.h>
函数原型:

int WINAPI WideCharToMultiByte(_In_ UINT CodePage,_In_ DWORD dwFlags,_In_NLS_string_(cchWideChar) LPCWCH lpWideCharStr,_In_ int cchWideChar,_Out_writes_bytes_to_opt_(cbMultiByte, return) LPSTR lpMultiByteStr,_In_ int cbMultiByte,_In_opt_ LPCCH lpDefaultChar,_Out_opt_ LPBOOL lpUsedDefaultChar
);

参数详解:

  • CodePage:指定执行转换的代码页字符集,可以为操作系统已安装或有效的任何代码页字符集,也可以指定其为下面的任意一值:
    CP_ACP:ANSI代码页;
    CP_MACCP:Macintosh代码页;
    CP_OEMCP:OEM代码页;
    CP_SYMBOL:符号代码页;
    CP_THREAD_ACP:当前线程ANSI代码页;
    CP_UTF7:使用UTF-7转换;
    CP_UTF8:使用UTF-8转换。
    使用最多的就是CP_ACP和CP_UTF8;
  • dwFlags:指定如何处理没有转换成功的字符,也可以不设此参数(设置为0),函数会运行的更快一些。对于UTF-8,dwflags必须为0或者WC_ERR_INVALID_CHARS,否则函数都将失败返回并设置错误码ERROR_INVALID_FLAGS,可以调用GetLastError获得;
  • lpWideCharStr:待转换为宽字符串;
  • cchWideChar:待转换的宽字符串的长度(字符个数),-1表示转换到字符串结尾;
  • lpMultiByteStr:转换后目的字符串缓冲区;
  • cbMultiByte:目的字符串缓冲区大小(单位字节)。如果设置为0,函数将返回所需缓冲区大小而忽略lpMultiByteStr;
  • lpDefaultChar:指向字符的指针,在指定编码里找不到相应字符时使用此字符作为默认字符替代。如果为NULL,则使用系统默认字符。使用dwFlags时不能使用此参数,否则报ERROR_INVLID_PARAMETER错误。
  • lpUsedDefaultChar:开关变量的指针,表明是否使用过默认字符。对于要求此参数为NULL的dwflags而使用此参数,函数将失败返回,并设置错误码ERROR_INVLID_PARAMETER。lpDefaultChar和lpUsedDefaultChar都设为NULL,函数会更快一些。

函数返回值:如果函数运行成功,并且cbMultiByte不为零,返回值是由 lpMultiByteStr指向的缓冲区中写入的字节数;如果函数运行成功,并且cbMultiByte为零,返回值是接存放目的字符串缓冲区所必需的字节数。如果函数运行失败,返回值为零。若想获得更多错误信息,请调用GetLastError函数。

代码示例:将wstr中的字符转换为多字符集字符存储到缓冲字符串str中

    WCHAR* wstr = L"Hollo 中国";char* str = NULL;//计算所需缓冲区大小,参数四-1表示转换到字符串尾,参数六NULL表示计算并返回缓冲区大小,最后两个参数传NULL即可int lpMultiByteStr = WideCharToMultiByte(CP_ACP, NULL, wstr, -1,str,NULL,NULL,NULL);//动态申请缓冲区内存str = new char[lpMultiByteStr];//将转换后的字符串写进缓冲区,最后两个参数传NULL即可WideCharToMultiByte(CP_ACP, NULL, wstr, -1, str, lpMultiByteStr, NULL, NULL);//输出测试setlocale(LC_ALL, str);cout << str << endl;//释放缓冲区内存空间delete[] str;str = NULL;
(2)MultiByteToWideChar()

函数功能:多字节字符串到款字节字符串的转换;
头文件:< windows.h>
函数原型:

int WINAPI MultiByteToWideChar(_In_ UINT CodePage,_In_ DWORD dwFlags,_In_NLS_string_(cbMultiByte) LPCCH lpMultiByteStr,_In_ int cbMultiByte,_Out_writes_to_opt_(cchWideChar, return) LPWSTR lpWideCharStr,_In_ int cchWideChar
);

参数详解:
- CodePage:同上;
- dwFlags:指定是否转换成预制字符或合成的宽字符,是否使用象形文字替代控制字符,以及如何处理无效字符。对于UTF-8,dwflags必须为0或者WC_ERR_INVALID_CHARS,否则函数都将失败返回并设置错误码ERROR_INVALID_FLAGS,可以调用GetLastError获得;
- lpMultiByteStr:多字节字符串;
- cbMultiByte:待转换的多字节字符串长度,-1表示转换到字符串结尾;
- lpWideCharStr:存放转换后的宽字符串缓冲;
- cchWideChar:宽字符串缓冲的大小(单位字符数)。

返回值:如果函数运行成功,并且cchWideChar不为零,返回值是由 lpWideCharStr指向的缓冲区中写入的字符数;如果函数运行成功,并且cchWideChar为零,返回值是接存放目的字符串缓冲区所必需的字符数。如果函数运行失败,返回值为零。若想获得更多错误信息,请调用GetLastError函数。

代码示例:将str中的字符转换为多字符集字符存储到缓冲字符串wstr中

    char str[] = "Hollo 中国";WCHAR* wstr = NULL;//计算所需缓冲区大小,参数四-1表示转换到字符串尾,参数六NULL表示计算并返回缓冲区大小int lpMultiByteStr = MultiByteToWideChar(CP_ACP,NULL,str,-1,wstr,NULL);//动态申请缓冲区内存wstr = new wchar_t[lpMultiByteStr];//将转换后的字符串写进缓冲区MultiByteToWideChar(CP_ACP, NULL, str, -1, wstr, lpMultiByteStr);//输出测试_wsetlocale(LC_ALL, L"chs"); //简体中文的locale名称为:"chs"简体中文的locale名称为:"chs"wprintf(wstr);//释放缓冲区内存空间delete[] wstr;wstr = NULL;

参考资料
Dablelv的博客
http://blog.csdn.net/k346k346/article/details/50082705
白永辉的专栏
http://blog.csdn.net/xiaobai1593/article/details/7387889
感谢博主的好文!

这篇关于mbs字符串(char*)与Unicode字符串(wchar_t*)的转换.md的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1068063

相关文章

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

在java中如何将inputStream对象转换为File对象(不生成本地文件)

《在java中如何将inputStream对象转换为File对象(不生成本地文件)》:本文主要介绍在java中如何将inputStream对象转换为File对象(不生成本地文件),具有很好的参考价... 目录需求说明问题解决总结需求说明在后端中通过POI生成Excel文件流,将输出流(outputStre

python+opencv处理颜色之将目标颜色转换实例代码

《python+opencv处理颜色之将目标颜色转换实例代码》OpenCV是一个的跨平台计算机视觉库,可以运行在Linux、Windows和MacOS操作系统上,:本文主要介绍python+ope... 目录下面是代码+ 效果 + 解释转HSV: 关于颜色总是要转HSV的掩膜再标注总结 目标:将红色的部分滤

利用Python开发Markdown表格结构转换为Excel工具

《利用Python开发Markdown表格结构转换为Excel工具》在数据管理和文档编写过程中,我们经常使用Markdown来记录表格数据,但它没有Excel使用方便,所以本文将使用Python编写一... 目录1.完整代码2. 项目概述3. 代码解析3.1 依赖库3.2 GUI 设计3.3 解析 Mark

C语言中的数据类型强制转换

《C语言中的数据类型强制转换》:本文主要介绍C语言中的数据类型强制转换方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C语言数据类型强制转换自动转换强制转换类型总结C语言数据类型强制转换强制类型转换:是通过类型转换运算来实现的,主要的数据类型转换分为自动转换

python中字符串拼接的几种方法及优缺点对比详解

《python中字符串拼接的几种方法及优缺点对比详解》在Python中,字符串拼接是常见的操作,Python提供了多种方法来拼接字符串,每种方法有其优缺点和适用场景,以下是几种常见的字符串拼接方法,需... 目录1. 使用 + 运算符示例:优缺点:2. 使用&nbsjsp;join() 方法示例:优缺点:3

java字符串数字补齐位数详解

《java字符串数字补齐位数详解》:本文主要介绍java字符串数字补齐位数,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java字符串数字补齐位数一、使用String.format()方法二、Apache Commons Lang库方法三、Java 11+的St

C++字符串提取和分割的多种方法

《C++字符串提取和分割的多种方法》在C++编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时,本文将详细探讨如何使用C++标准库中的工具来提取和分割字符串,并分析不同方法的适用... 目录1. 字符串提取的基本方法1.1 使用 std::istringstream 和 >> 操作符示

Java实现XML与JSON的互相转换详解

《Java实现XML与JSON的互相转换详解》这篇文章主要为大家详细介绍了如何使用Java实现XML与JSON的互相转换,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. XML转jsON1.1 代码目的1.2 代码实现2. JSON转XML3. JSON转XML并输出成指定的