首页 > 其他分享 >多字节字符串和宽字节字符串相互转换

多字节字符串和宽字节字符串相互转换

时间:2024-09-02 20:38:42浏览次数:9  
标签:wcs 转换 字节 dBufSize sBuf mbstr 字符串 wchar


#define _CRT_SECURE_NO_WARNINGS

/*多字节转宽字节*/

int unsafe_mbstowcs()
{
    // 设置当前的 locale 为用户环境变量指定的 locale
    setlocale(LC_ALL, "");
    // 定义多字节字符串
    const char* mbstr = "Hello, 世界!";
    // 计算需要的缓冲区大小
    size_t wcs_len = mbstowcs(NULL, mbstr, 0) + 1;
    // 分配宽字符缓冲区
    wchar_t* wcs = (wchar_t*)malloc(wcs_len * sizeof(wchar_t));
    if (wcs == NULL)
    {
        perror("malloc");
        return 1;
    }

    // 进行转换
    mbstowcs(wcs, mbstr, wcs_len);
    // 打印宽字符字符串
    wprintf(L"%ls\n", wcs);
    // 释放内存
    free(wcs);

    return 0;
}

int safe_mbstowcs_s()
{
    // 设置当前的 locale 为用户环境变量指定的 locale
    setlocale(LC_ALL, "");

    // 定义多字节字符串
    const char* mbstr = "Hello, 世界!";
    // 计算需要的缓冲区大小
    size_t wcs_len /*= strlen(mbstr) + 1*/; // 其实直接这样也可以,大一点空间也无所谓
    // 首先获取所需的宽字符数量
    mbstowcs_s(&wcs_len, NULL, 0, mbstr, _TRUNCATE);
    // 分配宽字符缓冲区
    wchar_t* wcs = (wchar_t*)malloc(wcs_len * sizeof(wchar_t));
    if (wcs == NULL)
    {
        perror("malloc");
        return 1;
    }

    // 安全转换
    size_t retVal = 0;
    // retVal:参数返回值,函数是否成功。
    // wcs: 宽字节缓存区地址。
    // wcs_len:是宽字符的数量,不是字节数
    // mbstr: 源多字节地址
    // _TRUNCATE:表示遇到字符串最后的空为止, 需要转换的源多字节最大数量(不包含最后的\0)
    auto errVal = mbstowcs_s(&retVal, wcs, wcs_len, mbstr, _TRUNCATE);
    //auto errVal = mbstowcs_s(&retVal, wcs, wcs_len, mbstr, strlen(mbstr)-4);// 只打印出:Hello, 世
    // 打印宽字符字符串
    wprintf(L"%ls\n", wcs);
    // 释放内存
    free(wcs);

    return 0;
}

int win_multibytetowidechar()
{
    // 设置当前的 locale 为用户环境变量指定的 locale
    setlocale(LC_ALL, "");

    unique_ptr<char[]> sBufArr(new char[50]{ 0 });
    char* sBuf = sBufArr.get();
    strcpy_s(sBuf, 50, "Hello, World! 你好,世界!");
    size_t sBufSize = strlen(sBuf) + 1; // must add 1

    //获取输出缓存大小
    //VC++ 默认使用ANSI,故取第一个参数为CP_ACP
    INT dBufSize = MultiByteToWideChar(CP_ACP, 0, sBuf, sBufSize, NULL, 0);
    printf("需要wchar_t%u个\n", dBufSize);

    unique_ptr<wchar_t[]> dBufArr(new wchar_t[dBufSize] {0});
    wchar_t* dBuf = dBufArr.get();
    wmemset(dBuf, 0, dBufSize);

    //进行转换
    int nRet = MultiByteToWideChar(CP_ACP, 0, sBuf, sBufSize, dBuf, dBufSize);
    if (nRet <= 0)
    { // 失败
    }
    else
    {// 成功
        wprintf(L"nRet = %d, mstr = %ls\n", nRet, dBuf);
    }

    return nRet;
}

/*宽字节转多字节*/
int unsafe_wcstombs()
{
    const wchar_t* wc = L"hi, 你好!";
    auto size_wc = 2 * (wcslen(wc) + 1);
    char* mb = (char*)malloc(size_wc);

    size_t ret = wcstombs(mb, wc, size_wc);
    printf("ret=%d %s\n", ret, mb);

    free(mb);
    return ret;
}

int safe_wcstombs_s()
{
    const wchar_t* wstr = L"hi, 你好!";
    size_t len /*= wcslen(wstr) + 1*/; // 其实直接这样也可以,大一点空间也无所谓
    // 首先获取所需的多字节数量 
    wcstombs_s(&len, NULL, 0, wstr, _TRUNCATE);
    /*len *= 2;*/
    char* mb = (char*)malloc(len);

    size_t ret_cnt;
    errno_t res = wcstombs_s(&ret_cnt, mb, len, wstr, _TRUNCATE);
    if (res != 0)
    {//fail
    }
    else
    {//success
        printf("%d  %s\n", ret_cnt, mb);
    }

    free(mb);
    return res;
}

int win_widerchartomultibyte()
{
    // 设置当前的 locale 为用户环境变量指定的 locale
    setlocale(LC_ALL, "");

    unique_ptr<wchar_t[]> sBufArr(new wchar_t[50]{ 0 });
    wchar_t* sBuf = sBufArr.get();
    wcscpy_s(sBuf, 50, L"Hello, World! 你好,世界!");
    size_t sBufSize = wcslen(sBuf) + 1;

    //获取输出缓存大小 NULL 表示到字符串结尾
    INT dBufSize = WideCharToMultiByte(CP_OEMCP, 0, sBuf, -1, NULL, 0, NULL, FALSE);
    printf("需要char%u个\n", dBufSize);

    unique_ptr<char[]> dBufArr(new char[dBufSize] {0});
    char* dBuf = dBufArr.get();
    memset(dBuf, 0, dBufSize);

    //进行转换
    int nRet = WideCharToMultiByte(CP_OEMCP, 0, sBuf, -1, dBuf, dBufSize, NULL, FALSE);
    if (nRet <= 0)
    { // 失败
    }
    else
    {// 成功
        printf("nRet = %d, mstr = %s\n", nRet, dBuf);
    }

    return nRet;
}

输出:

Hello, 世界!
Hello, 世界!
需要wchar_t21个
nRet = 21, mstr = Hello, World! 你好,世界!
ret=10 hi, 你好!
11  hi, 你好!
需要char26个
nRet = 26, mstr = Hello, World! 你好,世界!
请按任意键继续. . .




参考: https://www.cnblogs.com/ranjiewen/p/5770639.html

标签:wcs,转换,字节,dBufSize,sBuf,mbstr,字符串,wchar
From: https://www.cnblogs.com/huvjie/p/18393304

相关文章

  • 行转列,值转换成列
      1.值转换成列操作。值转列操作:[1777题库] 表:Products+-------------+---------+|ColumnName|Type|+-------------+---------+|product_id|int||store|enum||price|int|+-------------+---------+在SQL中,(prod......
  • 第十讲:怎么给字符串字段加索引?
    第十讲:怎么给字符串字段加索引?​ 现在,几乎所有的系统都支持邮箱登录,如何在邮箱这样的字段上建立合理的索引,是我们今天要讨论的问题。总概类似邮箱登录系统的长表索引假设,你现在维护一个支持邮箱登录的系统,用户表是这么定义的:mysql>createtableSUser(IDbigintunsigned......
  • 【4.0】字符串的内置方法
    【一】字符串内置方法#【1】字符串拼接#"+"可以字符串拼接#''.join(可迭代类型)借助元组或者列表print(''.join(["1","2","3"]))#123print("-".join("coll"))#c-o-l-lprint("*".join({"fit",......
  • 使用C++编写程序,提示并输入一个字符串,统计其中的英文字符,数字,空格以及其他字符的数量
    由于c++兼容c语言的程序,所以子函数使用了c语言的内容#include<iostream>#include<string.h>usingnamespacestd;voidCount(constcharstr[]){intletter=0,num=0,space=0,etc=0;while(*str!='\0'){if((*str>='a'&&*......
  • 【算法每日一练及解题思路】多种方式判断指定字符串其是否为回文字符串
    一、题目:给定一个字符串,判断其是否为回文字符串:二、举例:回文字符串是指一个字符串正读和反读都一样的字符串。例如,“level”、“radar”和“noon”都是回文字符串,因为它们从前往后读和从后往前读都是一样的在Java中,有多种方法可以判断一个字符串是否为回文字符串。以下是......
  • Apache SeaTunnel 2.3.7发布:全新支持大型语言模型数据转换
    我们欣喜地宣布,ApacheSeaTunnel2.3.7版本现已正式发布!作为一个广受欢迎的下一代开源数据集成工具,ApacheSeaTunnel一直致力于为用户提供更加灵活、高效的数据同步和集成能力。此次版本更新不仅引入了如LLM(大型语言模型)数据转换支持、增强的SQL支持和新连接器支持等多个新......
  • 6.字符串类型和年龄游戏的升级
    数字和字符串类型对字符串的操作有如下变量name="aleX",请按照要求实现每个功能:1.移除name变量对应的值两边的空格,并输出处理结果2.判断name变量对应的值是否以"al"开头,并输出结果3.判断name变量对应的值是否以"X"结尾,并输出结果4.将name变量对应的值中的......
  • JAVA-IO流之字节的输入输出流
    一、IO流的分流按流的流向分为:输入流、输出流根据处理的数据类型分为:字节流、字符流在计算机中、将硬盘上的文件向内存中的流为输入流(读取)、将内存中的流输出到硬盘为输出流(写)二、java流-字节输入输出流概念:流可以理解为一个数据序列、输入流表示从一个源读取数据,输出流表......
  • 41. 强化训练-字符串类封装
    强化训练-字符串类封装myString类实现自定义的字符串类属性char*pString;维护在堆区真实开辟的字符数组intm_Size;字符串长度行为有参构造MyString(char*str)拷贝构造MyString(constMyString&str);析构~MyString();重载<<运算符重载>>运算符重载......
  • Java 运用字节流实现的针对对象的深拷贝
    对象序列化为字节流,再从字节流反序列化为新的对象。classSelfCloneSampleimplementsSerializable{publicSelfCloneSampledeepClone(){//万物归于字节流,对对象序列化后再反序列化,即可实现深拷贝SelfCloneSampleanother=null;try{......