最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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é)的,比如常見的MessageboxA與MessageBoxW函數(shù),這時(shí)候就會(huì)出現(xiàn)很多問(wè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í)沒有使用,這個(gè)可以根據(jù)具體情況而定,如果出現(xiàn)中文無(wú)法轉(zhuǎn)化的情況,就要考慮使用這個(gè)函數(shù)了

而且我都沒有接收轉(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++開發(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"哈哈哈哈啊";
}

以上兩種方法,如果寬字符串中沒有中文字符,則可不使用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)文章

  • C語(yǔ)言修煉之路悟徹?cái)?shù)組真妙理?巧用下標(biāo)破萬(wàn)敵上篇

    C語(yǔ)言修煉之路悟徹?cái)?shù)組真妙理?巧用下標(biāo)破萬(wàn)敵上篇

    在C語(yǔ)言和C++等語(yǔ)言中,數(shù)組元素全為指針變量的數(shù)組稱為指針數(shù)組,指針數(shù)組中的元素都必須具有相同的存儲(chǔ)類型、指向相同數(shù)據(jù)類型的指針變量。指針數(shù)組比較適合用來(lái)指向若干個(gè)字符串,使字符串處理更加方便、靈活
    2022-02-02
  • Qt中CQGUI框架之陰影圓角窗口實(shí)現(xiàn)

    Qt中CQGUI框架之陰影圓角窗口實(shí)現(xiàn)

    這篇文章主要介紹了Qt中CQGUI框架之陰影圓角窗口實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • C語(yǔ)言實(shí)現(xiàn)猜數(shù)字游戲

    C語(yǔ)言實(shí)現(xiàn)猜數(shù)字游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)猜數(shù)字游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • C語(yǔ)言實(shí)現(xiàn)線性動(dòng)態(tài)(單向)鏈表的示例代碼

    C語(yǔ)言實(shí)現(xiàn)線性動(dòng)態(tài)(單向)鏈表的示例代碼

    本文主要介紹了C語(yǔ)言實(shí)現(xiàn)線性動(dòng)態(tài)(單向)鏈表的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 使用C語(yǔ)言中的time函數(shù)獲取系統(tǒng)時(shí)間

    使用C語(yǔ)言中的time函數(shù)獲取系統(tǒng)時(shí)間

    在C語(yǔ)言中可以使用time函數(shù)來(lái)獲取系統(tǒng)時(shí)間,以下對(duì)time函數(shù)進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下
    2013-07-07
  • C++?類模板與成員函數(shù)模板示例解析

    C++?類模板與成員函數(shù)模板示例解析

    這篇文章主要為大家介紹了C++?類模板與成員函數(shù)模板示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • C語(yǔ)言實(shí)現(xiàn)快速排序改進(jìn)版

    C語(yǔ)言實(shí)現(xiàn)快速排序改進(jìn)版

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)快速排序的改進(jìn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • C++ 命名空間--namespace總結(jié)

    C++ 命名空間--namespace總結(jié)

    namespace中文意思是命名空間或者叫名字空間,下面這篇文章主要給大家介紹了關(guān)于C++中名稱空間namespace使用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起看看吧
    2021-09-09
  • 順序線性表的代碼實(shí)現(xiàn)方法

    順序線性表的代碼實(shí)現(xiàn)方法

    下面小編就為大家?guī)?lái)一篇順序線性表的代碼實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • C/C++中多態(tài)性詳解及其作用介紹

    C/C++中多態(tài)性詳解及其作用介紹

    這篇文章主要介紹了C/C++中多態(tài)性(polymorphism)詳解及其作用介紹,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09

最新評(píng)論

龙陵县| 潼关县| 林口县| 印江| 汶上县| 鞍山市| 吴桥县| 通州市| 平顶山市| 祁东县| 驻马店市| 湖口县| 汉沽区| 巴楚县| 富顺县| 广平县| 韶关市| 合阳县| 锦州市| 馆陶县| 日照市| 新乡市| 高雄市| 河东区| 梁平县| 琼结县| 宣威市| 卫辉市| 阳山县| 平乐县| 石首市| 苏尼特右旗| 徐汇区| 乐都县| 本溪市| 临夏县| 繁峙县| 米泉市| 高邑县| 咸丰县| 长白|