Windows编程下的字符串格式及编码问题

深入解析SMBIOS查询:从原理到跨平台实战指南 在系统管理与硬件识别领域,理解计算机硬件的静态标识信息是基础且关键的技术环节。SMBIOS(系统管理BIOS)作为主板固件中的标准化数据结构,其原理在于以表格形式固化存储硬件组件的“户口本”信息,如主板、处理器、内存的制造商、型号与序列号。这项技术的核心价值在于为软件授权绑定、驱动部署、硬件兼容性测试及故障排查提供了稳定可靠的硬件身份依据。在应用场景上,无论是运维脚本自动匹配服务器型号,还是安全软件进行设备指纹识别,都依赖对SMBIOS数据的准确获取与解析。本文聚焦于**硬件兼容性测试**与**软件授权绑定 阅读详情

大家在学习或者使用Windows编程中,经常会碰到字符串之间的转换,char*转LPCWSTR也是其中一个比较常见的转换。下面就列出几种比较常用的转换方法。大家可以根据自己的需求选择相对应的方法,下面来一起学习学习吧。

为什么总结这个问题

一些代码在其他平台下是正常的,但是在Windows环境下,经常遇到中文乱码的情况,很是头疼!

1、通过MultiByteToWideChar函数转换

MultiByteToWideChar函数是将多字节转换为宽字节的一个API函数,它的原型如下:

int MultiByteToWideChar( 
 UINT CodePage,   // code page 
 DWORD dwFlags,   // character-type options 
 LPCSTR lpMultiByteStr, // string to map 
 int cbMultiByte,  // number of bytes in string 
 LPWSTR lpWideCharStr, // wide-character buffer 
 int cchWideChar  // size of buffer 
);

LPCWSTR实际上也是CONST WCHAR *类型

 char* szStr = "测试字符串"; 
WCHAR wszClassName[256]; 
memset(wszClassName,0,sizeof(wszClassName)); 
MultiByteToWideChar(CP_ACP,0,szStr,strlen(szStr)+1,wszClassName, 
 sizeof(wszClassName)/sizeof(wszClassName[0]));

2、通过T2W转换宏

  char* szStr = "测试字符串";  
CString str = CString(szStr); 
USES_CONVERSION; 
LPCWSTR wszClassName = new WCHAR[str.GetLength()+1]; 
wcscpy((LPTSTR)wszClassName,T2W((LPTSTR)str.GetBuffer(NULL))); 
str.ReleaseBuffer();

3、通过A2CW转换

char* szStr = "测试字符串";  
CString str = CString(szStr); 
USES_CONVERSION; 
LPCWSTR wszClassName = A2CW(W2A(str)); 
str.ReleaseBuffer();

上述方法都是UniCode环境下测试的。

4.编码格式转换:ANSI,UTF-8,UNICODE字符在Windows下的转换

//convert_code.hpp
//调用后不要忘记delete[]掉

#pragma once
#include <windows.h>

static const wchar_t* ConvertUtf8ToUnicode(const char* _ansiUtf8)
{
	if (_ansiUtf8 == NULL)
	{
		return L"";
	}
	int len = MultiByteToWideChar(CP_UTF8, 0, _ansiUtf8, -1, NULL, 0);
	wchar_t* wszUnicode = new wchar_t[(size_t)len + 1];
	memset(wszUnicode, 0, ((size_t)len + 1) * sizeof(wchar_t));
	MultiByteToWideChar(CP_UTF8, 0, _ansiUtf8, -1, wszUnicode, len);
	return wszUnicode;
}


static const char* ConvertUnicodeToUtf8(const wchar_t* _szUnicode)
{
	if (_szUnicode == NULL)
	{
		return "";
	}
	int len = WideCharToMultiByte(CP_UTF8, 0, _szUnicode, -1, NULL, 0, NULL, NULL);
	char* szUtf8 = new char[(size_t)len + 1];
	memset(szUtf8, 0, ((size_t)len + 1) * sizeof(char));
	WideCharToMultiByte(CP_UTF8, 0, _szUnicode, -1, szUtf8, len, NULL, NULL);
	return szUtf8;
}


static const wchar_t* ConvertAnsiToUnicode(const char* _szAnsi)
{
	if (_szAnsi == NULL)
	{
		return L"";
	}
	int len = MultiByteToWideChar(CP_ACP, 0, _szAnsi, -1, NULL, 0);
	wchar_t* wszUnicode = new wchar_t[(size_t)len + 1];
	memset(wszUnicode, 0, ((size_t)len + 1) * sizeof(wchar_t));
	MultiByteToWideChar(CP_ACP, 0, _szAnsi, -1, wszUnicode, len);
	return wszUnicode;
}


static const char* ConvertUnicodeToAnsi(const wchar_t* _szUnicode)
{
	if (_szUnicode == NULL)
	{
		return "";
	}
	int len = WideCharToMultiByte(CP_ACP, 0, _szUnicode, -1, NULL, 0, NULL, NULL);
	char* szAnsi = new char[(size_t)len + 1];
	memset(szAnsi, 0, ((size_t)len + 1) * sizeof(char));
	WideCharToMultiByte(CP_ACP, 0, _szUnicode, -1, szAnsi, len, NULL, NULL);
	return szAnsi;
}


static const char* ConvertAnsiToUtf8(const char* _szAnsi)
{
	if (NULL == _szAnsi)
	{
		return "";
	}
	int dwAnsiLen = MultiByteToWideChar(CP_ACP, NULL, _szAnsi, -1, NULL, NULL);
	wchar_t* szTmpUnicode = new wchar_t[(size_t)dwAnsiLen + 1];
	memset(szTmpUnicode, 0, sizeof(wchar_t) * ((size_t)dwAnsiLen + 1));
	MultiByteToWideChar(CP_ACP, NULL, _szAnsi, -1, szTmpUnicode, dwAnsiLen);

	int dwUtf8Len = WideCharToMultiByte(CP_UTF8, 0, szTmpUnicode, -1, NULL, 0, NULL, NULL);
	char* szUtf8 = new char[(size_t)dwUtf8Len + 1];
	memset(szUtf8, 0, sizeof(char) * ((size_t)dwUtf8Len + 1));
	WideCharToMultiByte(CP_UTF8, 0, szTmpUnicode, -1, szUtf8, dwUtf8Len, NULL, NULL);
	delete[] szTmpUnicode;

	return szUtf8;
}


static const char* ConvertUtf8ToAnsi(const char* _szUtf8)
{
	if (NULL == _szUtf8)
	{
		return "";
	}
	int dwAnsiLen = MultiByteToWideChar(CP_UTF8, NULL, _szUtf8, -1, NULL, NULL);
	wchar_t* szTmpUnicode = new wchar_t[(size_t)dwAnsiLen + 1];
	memset(szTmpUnicode, 0, sizeof(wchar_t) * ((size_t)dwAnsiLen + 1));
	MultiByteToWideChar(CP_UTF8, NULL, _szUtf8, -1, szTmpUnicode, dwAnsiLen);

	int dwUtf8Len = WideCharToMultiByte(CP_ACP, 0, szTmpUnicode, -1, NULL, 0, NULL, NULL);
	char* szAnsi = new char[(size_t)dwUtf8Len + 1];
	memset(szAnsi, 0, sizeof(char) * ((size_t)dwUtf8Len + 1));
	WideCharToMultiByte(CP_ACP, 0, szTmpUnicode, -1, szAnsi, dwUtf8Len, NULL, NULL);
	delete[] szTmpUnicode;

	return szAnsi;
}

5. utf-8和GBK转换

除了一些旧的、没有考虑到兼容性的网页还在用gbk做编码外,大部分的网页都已经用utf-8做编码了。但是最令人头疼的是,windows的控制台是很不好显示utf-8的。

#include <string>
#include <windows.h>
using std::string;

//gbk 转 utf8
string GBKToUTF8(const string& strGBK)
{
    string strOutUTF8 = "";
    WCHAR * str1;
    int n = MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, NULL, 0);
    str1 = new WCHAR[n];
    MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, str1, n);
    n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);
    char * str2 = new char[n];
    WideCharToMultiByte(CP_UTF8, 0, str1, -1, str2, n, NULL, NULL);
    strOutUTF8 = str2;
    delete[]str1;
    str1 = NULL;
    delete[]str2;
    str2 = NULL;
    return strOutUTF8;
}

//utf-8 转 gbk
string UTF8ToGBK(const string& strUTF8)
{
    int len = MultiByteToWideChar(CP_UTF8, 0, strUTF8.c_str(), -1, NULL, 0);
    unsigned short * wszGBK = new unsigned short[len + 1];
    memset(wszGBK, 0, len * 2 + 2);
    MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUTF8.c_str(), -1, wszGBK, len);

    len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
    char *szGBK = new char[len + 1];
    memset(szGBK, 0, len + 1);
    WideCharToMultiByte(CP_ACP,0, wszGBK, -1, szGBK, len, NULL, NULL);
    //strUTF8 = szGBK;
    std::string strTemp(szGBK);
    delete[]szGBK;
    delete[]wszGBK;
    return strTemp;
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

参考资料

http://www.cppblog.com/Shihira/archive/2013/10/28/200124.aspx

为什么Windows中文默认编码不是UTF-8?文本框输入法输入英文字符wm或者中文“我们“, 程序内部是什么编码?为什么VS编译UTF-8格式源代码, 代码中字符串却是ANSI编码? UTF-8编码出现的比中文编码更晚,这造成了Windows在大陆必须先用中文编码。虽然到21世纪,流行UTF-8编码,但也不能直接改掉,避免大量不兼容的问题。 阅读详情

相关推荐

STM32+CubeMX实战:5步搞定LWIP HTTP服务器搭建(附常见编译错误解决)

本文详细介绍了基于STM32和CubeMX平台,快速搭建LWIP HTTP服务器的5步实战指南。内容涵盖从项目初始化、LWIP深度配置到解决经典的`HTTPD_FSDATA_FILE`编译错误,并分享了使用VSCode进行高效开发的工作流,旨在帮助嵌入式开发者快速实现网络功能并规避常见陷阱。

weixin_29192365的博客 574

WCHAR等宽体字符的转换

WCHAR等宽体字符的转换 1,首先是WCHAR转成char     WCHAR wc2[5];   char str[10];   wcstombs(str, wc2, 9); 2,char到WCHAR  WideCharToMultiByte(CP_ACP, NULL, wc2, wcslen(wc2) + 1, str, 10, 0, 0); 或者  WCHAR wsz

cqltbe131421的博客 660

DAC8760高精度数模转换器原理与工业级嵌入式应用

数模转换器(DAC)是工业测控系统中实现数字指令到模拟执行的关键接口,其核心性能由分辨率、线性度、温漂及系统级TUE(总未调整误差)共同决定。DAC8760作为一款16位四象限精密DAC,集成了可编程增益放大器(PGA)、内部基准源与SPI高速接口,支持电压/电流双模输出,显著提升闭环控制精度与硬件适配灵活性。其技术价值在于将高精度模拟前端与数字控制深度耦合,满足PLC、ATE及激光偏置等严苛场景对长期稳定性与多通道同步性的要求。本文围绕DAC8760的寄存器配置、HAL/LL驱动实践、PCB布局规范、现场

weixin_42315569的博客 583

Windows下多字节字符转宽字符

这个代码页都是指多字节字符串的代码页,MultiByteToWideChar的源字符串和WideCharToMultiByte的目标字符串的代码页。MultiByteToWideChar调用两遍,第一次调用,buff用的NULL,目的是计算转换后字符个数,便于申请内存。1. 调用A结尾的API, 使用多字节字符集函数处理后,转为Unicode字符串。2.调用W结尾的API,使用宽字符集函数处理后,就是Unicode字符串。说了一个奇怪的情况, API用的宽字符版本,代码却是使用多字节字符集。

caz28的专栏 593

Matlab使用GitHub的踩坑记录(持续更新)

Matlab使用git的踩坑记录前言Matlab设置Git的官方帮助文档系统配置新建Git两种代码管理方式典型源代码管理SVN分布式源代码管理 Git注意:SVN和Git都可以用GitHub创建新的库 前言 作为Git初学者,对Git的代码版本管理非常非常喜欢,给了我极大的安全感。特别是想到之前的几次Matlab、Latex和python的代码莫名其妙被折腾没了又没法找回的悲剧,决定慢慢的走入gi...

voluntry的博客 7298

新手避坑指南:用SARScape 5.6.2处理Sentinel-1数据做SBAS-InSAR,这些参数设置错了白忙活

本文详细介绍了使用SARScape 5.6.2处理Sentinel-1数据做SBAS-InSAR时的关键参数设置技巧,帮助新手避免常见错误。重点解析了连接图生成、干涉工作流、DEM处理等环节的12个关键参数,包括Max Normal Baseline、Unwrapping Coherence Threshold等,提供实测安全值范围和优化建议,确保处理效率和结果准确性。

weixin_30694389的博客 558

Window Server 中 JDK 默认编码格式设置

Window Server 中 JDK 默认编码格式设置

青云的博客 2218

中科蓝讯AB536X/AB892X芯片开发避坑指南:Downloader配置中那些容易忽略的细节

本文详细解析中科蓝讯AB536X/AB892X芯片开发中Downloader配置的关键细节,包括软开关机实现、触摸灵敏度调试、量产校频等常见问题。特别针对无PR口芯片的替代方案、触摸参数优化、校频流程等易忽略环节提供实用解决方案,帮助开发者规避量产风险,提升开发效率。

weixin_30687051的博客 476

C++之创建Windows系统服务

Microsoft Windows 服务(即,以前的 NT 服务)使您能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序。这些服务可以在计算机启动时自动启动,可以暂停和重新启动而且不显示任何用户界面。这种服务非常适合在服务器上使用,或任何时候,为了不影响在同一台计算机上工作的其他用户,需要长时间运行功能时使用。

草上爬的博客 5621

【ATC/DTC方法第四期】GOT09-dT-tao 昼夜温度周期模型方法介绍(含Python代码实现)

GOT09-dT-tao 模型是一种经过简化和参数固定的 昼夜温度周期模型(Diurnal Temperature Cycle, DTC)。它从 GOT09 模型(Göttsche and Olesen, 2009)衍生而来,但更加轻量化,更适合在数据不足或参数估计困难的情境下使用。

WW、forever的博客 147

软件测试面试题之易错题

(1)白盒测试:又称功能功能 测试、数据驱动测试和行为测试,是一种从用户观点出发的测试,被测程序为黑盒子, 通过测试来检测每个功能是否能够正常使用。(2)黑盒测试:又称结构测试和逻辑驱动 测试,是知道产品内部工作过程,通过测试来检测产品内部动作是否按照规格说明书 的规定去正常运行。(1)、测试需求分析;(2)动态白盒测试:需要对各个模块功能、模块间的接口、局部数据结构、主要执行路径、 错误处理等方面的测试。(2) 集成测试所测试的对象是模块间的接口,其目的是在找出在模块接口上面,包括整体体系结构上的问题;

m0_37449634的博客 679

windows更改语言中编码格式

在dos(win+R,cmd),输入chcp 936,chcp65001(UTF-8)编码。 更改编码,带来一些列问题,文件名和程序菜单出现乱码。运行正常的程序,由于目录和文件名的乱码原因,出现问题。 可以通过控制面板的时间和语言按钮,改回正常编码格式:如图: 以上图片顺序点过来,最后的beta版,utf-8点掉,就恢复正常了我。 ...

qq_43596960的博客 2776

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

windows区域格式英文系统c++加载中文路径乱码问题

电脑语言的区域格式设置为英文后,系统默认编码不再是gbk,可通过cmd属性查看代码页,我的是oem437,也就是窄字符(应该无论如何也无法保存中文)。(这里无法用的意思是,我们通过cmd的dir输出一个中文路径,虽无法显示,但是复制到记事本不会乱码,但是我们程序输出的仍然乱码)程序cout和printf输出的似乎也有区别,最好用printf输出。//一定要加1,不然会出现尾巴。// 将字符转换为8位二进制表示。通过此网站比对https://www.qqxiuzi.cn/bianma/zifuji.php。

IM_Crazy的博客 1320

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

跨平台程序的UNICODE字符串处理方法。

在windows下面编程,我们通常都知道unicode这个概念,如果一个程序是unicode的,那么他将调用unicode的api。这个时候,所有传递给api的字符串参数都要是unicode的.如果使用C的风格,是很简单的,字符串全部由char* str 转变成TCHAR* str,使用的crt函数(其实也是api)时调用_tcslen类的函数族就可以了。在讨论其它问题前要先明确一个概念:unic

waterflier's BLOG 2839

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

乱码 字符集 编码格式

真正的转码应该是 原始数据GBK编码,你给我转成UTF-8,完成这种功能需要自己根据2个。编程语言的编码格式:比如说C++,java 语言,在我们需要将一个字节数组转成字符串时。而数据传输IO流肯定是以字节(二进制数据)的形式,不会发生乱码,当我们读取文件、数据发生乱码时,要先确认原数据的编码格式,其实严格来讲上面说的并不是什么转码,只是数据的还原。指的是代码保存的编码格式或者要读取文件的编码格式。总之,原数据是什么编码,读取要使用对应的编码。而原数据是UTF-8 导致读取的数据乱码。

weixin_43803780的博客 579

Window API 使用的一些注意事项

Window API 使用的一些注意事项

森明帮大于黑虎帮的博客 1369

oracle用len函数,使用slen函数

jni和C++通信中文乱码的问题http://www.cnblogs.com/bluesky4485/archive/2011/12/13/2285802.html首先,需要明确几个关于编码的基本概念:java内部是使用的16bit的unicode编码(utf-16)来表示字符串的,无论英文还是中文都是2字节;...文章一叶飘舟2011-12-161414浏览量【C语言】学习笔记9——结构stru...

weixin_28968629的博客 1434

我的Python之路【第一篇】:Python简介和入门

1.搭建Python环境 windows下搭建python环境 1.下载安装包 2.Windows中Python的安装包是后缀名为msi的安装包,直接双击下一步即可 3.Windwos环境下默认的安装路径是:C:\Python27 4.添加环境变量 【右键计算机】-->【点击属性】-->【高级系统设置】-->【高级】-->【环境变量】-->...

weixin_33850890的博客 100

BUUCTF 打卡3

之前一直觉得没有学,所以碰到不会的大概率都会划走。但想想,总该要面对的。 不知道并不可怕,不知道还不去学才可怕。 1. 丢失的MD5 可以看出这段代码是在py2中运行的。 解出来的就是flag。 2.Alice与Bob???? 根据题目要求,将素数98554799767分解为101999和966233,并组成新的数101999966233,然后进行md5的32位小写哈希。 (为什么用py2的md5库运行不是正确答案???) 3.Windows系统密码 windows下密码的格式: Windows系统下的

qq_52193383的博客 444

windows编程字符串处理

Windows编程中主要使用两种字符串类型:ANSI字符串(char)和Unicode字符串(wchar_t)。ANSI字符串使用单字节编码,而Unicode字符串使用双字节编码(UTF-16)。为了编写跨平台的代码,Windows提供了TCHAR类型,它可以根据编译设置自动转换为char或wchar_t。CRT库中提供了对应的处理函数,如strlen和wcslen分别用于处理ANSI和Unicode字符串。提示:以下是本篇文章正文内容,下面案例可供参考。

qq_37077309的博客 1206

Windows核心编程:字符和字符串处理

作者:shenzi链接:http://hi.youkuaiyun.com/shenziWindows核心编程:字符和字符串处理1.字符编码    ANSI字符,一个字符一字节(8位),最多只能表达256个字符。    UTF的全称是Unicode Transformation Format(Unicode转换格式)。    UTF

shenzi的天空 3308

PYCHARM 编码问题

最近在使用WINDOWS + PYCHARM 环境编写一些脚本时,发现print 会导致编码错误,如以下。 print接收字符串参数,python3字符串采用unicode编码。 从表面上看, 应该是在unicode编码转成GBK编码时候,发生错误。 \ufffd 这个unicode码值,没有对应的GBK编码。表面的意思是明白了,但是为什么会发生这个错误呢。花了一些时间搜索调试去理解这个问题。UnicodeEncodeError: 'gbk' codec can't encode character '\

花括号的博客 5268

常见开发语言在 Windows 上的默认编码格式

字符串是字节流,输出编码取决于手动设置(如 header 或 mb_* 函数)

A185822153的专栏 883

不同地区(语言)windows系统的字符串乱码问题

windows字符编码问题

Kelvin_Yan的专栏 1668
上一篇: 最好用的json库,也许是JSON for modern C++ 的最佳实践!解决nlohmann json中文无法解析的问题!
下一篇: Windows环境下读取文件,输出中文乱码原因剖析及解决方案!
CodeBowl
博客等级 码龄5年 7664粉丝 67原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值