欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C/C++寬窄字符轉(zhuǎn)換與輸出的多種實(shí)現(xiàn)方法

 更新時(shí)間:2022年08月08日 08:27:41   作者:IT余識(shí)  
本文主要介紹了C/C++寬窄字符轉(zhuǎn)換與輸出的多種實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

如果是C/C++程序員,對(duì)于VS應(yīng)該是不陌生的,可謂是C/C++程序手中的利器

但如果稍微深入學(xué)習(xí)就會(huì)發(fā)現(xiàn),windows API大部分都是分為寬字節(jié)與窄字節(jié)的,比如常見(jiàn)的MessageboxA與MessageBoxW函數(shù),這時(shí)候就會(huì)出現(xiàn)很多問(wèn)題,最常見(jiàn)的便是亂碼

需要注意的是,WIndows底層函數(shù)均采用的是寬字節(jié),即使你使用的是char,程序真正執(zhí)行的時(shí)候,還是會(huì)在底層將char轉(zhuǎn)化為wchar_t,這就意味著使用窄字節(jié)效率是比不上寬字節(jié)

同時(shí)需要知道.wchar_t是支持多個(gè)國(guó)家語(yǔ)言的,而char只支持本國(guó)語(yǔ)言.

一、什么是寬字節(jié)?什么是窄字節(jié)?

認(rèn)識(shí)寬窄字節(jié)最好的辦法就是動(dòng)手實(shí)驗(yàn)一下

可以看到,最直接的影響就是大小,char只占一個(gè)字節(jié),而wchar_t要占兩個(gè)字節(jié),并且需要在字符串前加 L 才表示是寬字節(jié)

其實(shí)還有很多細(xì)節(jié),比如這里是使用的字符c,如果是使用的漢字,還能正常使用嗎?很多問(wèn)題需要自己碰到并解決,最后才能是自己的東西

二、寬窄字節(jié)之間的轉(zhuǎn)化方法

1.Windows API進(jìn)行轉(zhuǎn)化

頭文件:

#include<Windows.h>

用到的函數(shù)

窄字節(jié)轉(zhuǎn)寬字節(jié):

int MultiByteToWideChar(
UINT    CodePage,  //要轉(zhuǎn)換的代碼頁(yè),一般直接填CP_ACP,表示當(dāng)前系統(tǒng)使用的代碼頁(yè)
DWORD   dwFlags, //轉(zhuǎn)換標(biāo)志,直接填0即可
LPCCH lpMultiByteStr, //要轉(zhuǎn)換的窄字節(jié)字符串
int   cbMultiByte, //窄字節(jié)字符串的長(zhǎng)度,以字節(jié)計(jì)算
LPWSTR  lpWideCharStr, //存放轉(zhuǎn)換完成的寬字符緩沖區(qū)
int    cchWideChar //存放寬字符緩沖區(qū)的大小
);

寬字節(jié)轉(zhuǎn)窄字節(jié):

int WideCharToMultiByte(
UINT CodePage,//要轉(zhuǎn)換的代碼頁(yè),一般直接填CP_ACP,表示當(dāng)前系統(tǒng)使用的代碼頁(yè)
 DWORD dwFlags,//轉(zhuǎn)換標(biāo)志,直接填0即可
LPCWCH lpWideCharStr,//要轉(zhuǎn)換的寬字節(jié)字符串
int cchWideChar, //寬字節(jié)字符串的長(zhǎng)度,以字符計(jì)算
LPSTR lpMultiByteStr, //存放轉(zhuǎn)換完成的窄字符緩沖區(qū)
 int cbMultiByte, //存放寬字符緩沖區(qū)的大小
LPCCH lpDefaultChar, //如果字符無(wú)法轉(zhuǎn)換,則使用該字符填充,一般填0,默認(rèn)即可
LPBOOL lpUsedDefaultChar //如果出現(xiàn)無(wú)法轉(zhuǎn)換的字符,該參數(shù)被設(shè)為true,默認(rèn)填NULL即可
);

一般寬字符是窄字符字節(jié)長(zhǎng)度的兩倍,但也有可能出現(xiàn)意外情況,或者不想自己計(jì)算需要多大的緩沖,則可以調(diào)用兩次該函數(shù),第一次返回需要的大小,第二次進(jìn)行轉(zhuǎn)換

下面是我封裝的兩個(gè)函數(shù),可直接使用,但需要自己delete內(nèi)存,可以自己使用wstring和string進(jìn)行替換

窄字節(jié)轉(zhuǎn)寬字節(jié):

//str:要轉(zhuǎn)換的窄字符串
//len:接受轉(zhuǎn)換成功后寬字符的長(zhǎng)度,可直接填NULL,不接收
wchar_t* AtoW(const char* str, int* len)
{
	int wcLen = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
	wchar_t* newBuf = new wchar_t[wcLen + 1]{};
	MultiByteToWideChar(CP_ACP, 0, str, -1, newBuf, wcLen);
	if (len != NULL) {
		*len = wcLen;
	}
	return newBuf;
}

寬字節(jié)轉(zhuǎn)窄字節(jié)

//str:要轉(zhuǎn)換的寬字符串
//len:接受轉(zhuǎn)換成功后窄字符的長(zhǎng)度,可直接填NULL,不接收
char* WtoA(const wchar_t* str, int* len)
{
	int cLen = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, 0, NULL);
	char* newBuf = new char[cLen + 1]{};
	WideCharToMultiByte(CP_ACP, 0, str, -1, newBuf, cLen, 0, NULL);
	if (len != NULL) {
		*len = cLen;
	}
	return newBuf;
}

2.C/C++庫(kù)函數(shù)轉(zhuǎn)換

用到的頭文件:

#include<cstdlib> //包含轉(zhuǎn)換函數(shù)
#include<locale> //包含設(shè)置地域函數(shù)

用到的函數(shù):

設(shè)置地域,當(dāng)試圖轉(zhuǎn)換中文時(shí),需要設(shè)置,否則為亂碼

char* setlocale(
int  _Category, //設(shè)置該函數(shù)影響范圍,一般直接填LC_ALL,即全部影響
char const* _Locale //一般填空,即使用本地地域信息
);

標(biāo)準(zhǔn)窄轉(zhuǎn)寬:

size_t mbstowcs(
wchar_t    _Dest, //轉(zhuǎn)換后存放的地方
const char * _Source, //要轉(zhuǎn)換的內(nèi)容
size_t   _MaxCount //轉(zhuǎn)換后存放地方的大小,以字符個(gè)數(shù)計(jì)算
)

使用:

#define _CRT_SECURE_NO_WARNINGS //必須定義宏,否則VS報(bào)錯(cuò)
#include<iostream>
#include<cstdlib>
#include<locale>
using namespace std;
int main() {
	setlocale(LC_ALL, ""); //設(shè)置本地地域信息.否則轉(zhuǎn)換中文出現(xiàn)亂碼
	wchar_t buf[0xFF];
	mbstowcs(buf, "哈哈哈哈", 0xFF);
}

標(biāo)準(zhǔn)寬轉(zhuǎn)窄:

size_t wcstombs(
char*_Dest, //轉(zhuǎn)換后存放的地方
const wchar_t* _Source, //要轉(zhuǎn)換的內(nèi)容
size_t   _MaxCount //轉(zhuǎn)換后存放地方的大小,以字符個(gè)數(shù)計(jì)算
)

使用:

#define _CRT_SECURE_NO_WARNINGS //必須定義宏,否則VS報(bào)錯(cuò)
#include<iostream>
#include<cstdlib>
#include<locale>
using namespace std;
int main(){
	setlocale(LC_ALL,""); //設(shè)置本地地域信息.否則轉(zhuǎn)換中文出現(xiàn)亂碼
	char buf[0xFF];
	wcstombs(buf,L"哈哈哈哈哈",sizeof(buf));
}

安全函數(shù)窄轉(zhuǎn)寬:

errno_t mbstowcs_s(
size_t* _PtNumOfCharConverted, //接收轉(zhuǎn)換成功的字符個(gè)數(shù)
 wchar_t*    _DstBuf, //接受成功轉(zhuǎn)換的字符
size_t  _SizeInWords, //_DesBuf緩沖區(qū)大小,以字符計(jì)算
 char const* _SrcBuf, //要轉(zhuǎn)化的字符
 size_t      _MaxCount //最大要轉(zhuǎn)化的字符數(shù)量
    );

使用:

#include<iostream>
#include<cstdlib>
using namespace std;
int main() {
	wchar_t buf[0xFF];
	mbstowcs_s(NULL,buf,0xFF, "哈哈哈哈", 0xFF);
}

安全函數(shù)寬轉(zhuǎn)窄:

errno_t wcstombs_s(
size_t* _PtNumOfCharConverted, //接收轉(zhuǎn)換成功的字符個(gè)數(shù)
 wchar_t*    _DstBuf, //接受成功轉(zhuǎn)換的字符
size_t  _SizeInWords, //_DesBuf緩沖區(qū)大小,以字符計(jì)算
 char const* _SrcBuf, //要轉(zhuǎn)化的字符
 size_t      _MaxCount //最大要轉(zhuǎn)化的字符數(shù)量
    );

使用:

#include<iostream>
#include<cstdlib>
#include<locale>
using namespace std;
int main() {
	setlocale(LC_ALL,"");
	char buf[0xFF];
	wcstombs_s(NULL, buf, 0xFF, L"哈哈哈哈哈", sizeof(buf));
	printf("%s",buf);
}

大家可能看到,我有時(shí)使用了setlocal,有時(shí)沒(méi)有使用,這個(gè)可以根據(jù)具體情況而定,如果出現(xiàn)中文無(wú)法轉(zhuǎn)化的情況,就要考慮使用這個(gè)函數(shù)了

而且我都沒(méi)有接收轉(zhuǎn)化字符個(gè)數(shù),也就是第一個(gè)參數(shù),如果需要準(zhǔn)確接受轉(zhuǎn)化成功字符的個(gè)數(shù),就必須要使用setlocal函數(shù)

可能大家還看到過(guò)_wcstombs_s_l等函數(shù),這個(gè)函數(shù)還需要_create_locale與 _free_locale函數(shù)配合使用,考慮下來(lái),過(guò)于麻煩,不如上面的幾種轉(zhuǎn)化方法,所以便不予講解,大家有興趣可以去查看官網(wǎng)說(shuō)明,鏈接在此 函數(shù)說(shuō)明 設(shè)置本地說(shuō)明

3.ATL庫(kù)轉(zhuǎn)換

ATL模板庫(kù)是微軟推出的一個(gè)C++模板庫(kù),在visual studio中安裝了C++開(kāi)發(fā)環(huán)境就可以正常使用

寬轉(zhuǎn)窄:

#include<iostream>
#include<atlconv.h> //頭文件
using namespace std;
int main() {
    USES_CONVERSION; //必須添加
    wchar_t buf[] = L"哈哈哈哈哈哈";
    char *nbuf=W2A(buf); //使用??臻g進(jìn)行轉(zhuǎn)換,不需要delete
    cout << nbuf << endl;
}

窄轉(zhuǎn)寬:

#include<iostream>
#include<locale>
#include<atlconv.h> //頭文件
using namespace std;
int main() {
    setlocale(LC_ALL,""); //本地化,為輸出漢字
    USES_CONVERSION; //必須添加
    char buf[] = "哈哈哈哈哈哈";
    wchar_t *nbuf=A2W(buf); //使用??臻g進(jìn)行轉(zhuǎn)換,不需要delete
    wcout << nbuf;
}

4.COM組件轉(zhuǎn)換

寬轉(zhuǎn)窄:

#include<comutil.h>
#pragma comment(lib, "comsuppw.lib")
int main() {
	wchar_t str[] = L"哈哈哈";
	char *s=_com_util::ConvertBSTRToString(str); //轉(zhuǎn)換函數(shù)
	//其它操作
	delete[] s; //釋放內(nèi)存
}

窄轉(zhuǎn)寬:

#include<comutil.h>
#pragma comment(lib, "comsuppw.lib")
int main() {
	char str[] = "哈哈哈哈";
	wchar_t *s=_com_util::ConvertStringToBSTR(str); //轉(zhuǎn)換函數(shù)
	//其它操作
	SysFreeString(s); //釋放內(nèi)存
}

三.解決VS控制臺(tái)無(wú)法輸出寬字符問(wèn)題

方法一:使用setlocal和printf函數(shù):

#include<iostream>
#include<locale>
using namespace std;
int main() {
	setlocale(LC_ALL,"");
	printf("%ls",L"了解");
}

方法二:使用setlocal與wcout

#include<iostream>
#include<locale>
using namespace std;
int main() {
	setlocale(LC_ALL,"");
	wcout << L"哈哈哈哈啊";
}

以上兩種方法,如果寬字符串中沒(méi)有中文字符,則可不使用setlocal函數(shù)

方法三:使用WriteConsoleW函數(shù)

#include<Windows.h>
int main() {
	wchar_t buf[]=L"哈哈哈哈哈哈哈哈哈哈";
	WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),buf,sizeof(buf)/2, NULL, 0);
}

到此這篇關(guān)于C/C++寬窄字符轉(zhuǎn)換與輸出的多種實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)C/C++寬窄字符轉(zhuǎn)換與輸出內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺析多維數(shù)組的下標(biāo)重載

    淺析多維數(shù)組的下標(biāo)重載

    貼一下實(shí)現(xiàn)基本功能的代碼吧,像越界檢測(cè),及其他功能就沒(méi)寫了,只要體現(xiàn)了思路,其他的功能好加
    2013-09-09
  • C++Primer筆記之關(guān)聯(lián)容器的使用詳解

    C++Primer筆記之關(guān)聯(lián)容器的使用詳解

    本篇文章對(duì)C++Primer 關(guān)聯(lián)容器的使用進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下
    2013-05-05
  • C++實(shí)現(xiàn)LeetCode(158.用Read4來(lái)讀取N個(gè)字符之二 - 多次調(diào)用)

    C++實(shí)現(xiàn)LeetCode(158.用Read4來(lái)讀取N個(gè)字符之二 - 多次調(diào)用)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(158.用Read4來(lái)讀取N個(gè)字符之二 - 多次調(diào)用),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++中實(shí)現(xiàn)子進(jìn)程執(zhí)行和管道通信詳解

    C++中實(shí)現(xiàn)子進(jìn)程執(zhí)行和管道通信詳解

    在這篇博客中,我們將深入探索如何在 C++ 程序中實(shí)現(xiàn)子進(jìn)程的創(chuàng)建與執(zhí)行,以及父子進(jìn)程間的管道通信,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • 詳解C語(yǔ)言中的自定義類型

    詳解C語(yǔ)言中的自定義類型

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言中的四大自定義類型(結(jié)構(gòu)體、位段、枚舉和聯(lián)合)的相關(guān)知識(shí),文中的示例代碼簡(jiǎn)潔易懂,需要的可以參考一下
    2023-07-07
  • 關(guān)于C++11中限定作用域的枚舉類型的問(wèn)題

    關(guān)于C++11中限定作用域的枚舉類型的問(wèn)題

    C++中有兩種類型的枚舉:不限定作用域的枚舉類型和限定作用域的枚舉類型。限定作用域的枚舉類型是C++11標(biāo)準(zhǔn)引入的新類型,對(duì)C++11中限定作用域的枚舉類型相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-01-01
  • C++算法系列之中國(guó)農(nóng)歷的算法

    C++算法系列之中國(guó)農(nóng)歷的算法

    這篇文章主要介紹了C++計(jì)算中國(guó)農(nóng)歷的深入淺析,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • Qt 自定義分頁(yè)控件的實(shí)現(xiàn)

    Qt 自定義分頁(yè)控件的實(shí)現(xiàn)

    在應(yīng)用程序開(kāi)發(fā)時(shí)經(jīng)常會(huì)遇到數(shù)據(jù)分頁(yè)的需求,每一頁(yè)展示特定數(shù)量的數(shù)據(jù),通過(guò)點(diǎn)擊按鈕翻頁(yè)或者輸入頁(yè)碼跳轉(zhuǎn)到指定頁(yè),本文就來(lái)介紹一下Qt 自定義分頁(yè)控件的實(shí)現(xiàn),感興趣的可以了解一下
    2023-11-11
  • 淺談c語(yǔ)言中轉(zhuǎn)義字符的用法及注意事項(xiàng)

    淺談c語(yǔ)言中轉(zhuǎn)義字符的用法及注意事項(xiàng)

    下面小編就為大家?guī)?lái)一篇淺談c語(yǔ)言中轉(zhuǎn)義字符的用法及注意事項(xiàng)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-08-08
  • C語(yǔ)言實(shí)現(xiàn)獲取文件MD5值

    C語(yǔ)言實(shí)現(xiàn)獲取文件MD5值

    MD5(Message?Digest?Algorithm?5)是一種常用的哈希函數(shù)算法,這篇文章主要介紹了C語(yǔ)言如何獲取文件MD5值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-08-08

最新評(píng)論