wchar和char的了解以及相互轉化

2021-07-09 02:42:10 字數 4532 閱讀 6491

今天遇到wchar和char字元轉換的問題,花費了不少的時間。

typedef

struct tagserialdata

serial_data, *pserial_data;

這是我定義的結構體(nuwchar是公司自定義的,相當於wchar),但是另外公司的同事把結構體定義成了

struct tagserialdata

serial_data, *pserial_data;

所以導致我將自己定義的結構體的datalength賦值成10時,聯調的同事接收到的length=0;或者我將自己定義的結構體的serialdata賦值成「1234567890」時,同事接收到的length是乙個無限大的數

這是我給自己定義的結構體賦值,獲取長度

serial_data s_stcserialdata = ;

wcscpy(s_stcserialdata.serialdata,l"1234567890");

s_stcserialdata.datalength=wcslen(s_stcserialdata.serialdata)

後來發現定義的結構體不一樣時,我只好修改自己的結構體,變成nuchar,但是在後面的功能上我要用的是wchar型別的資料。這就需要我將他後來傳給我的char型別的資料轉換成wchar .

我在網上搜的wchar轉化成char的例子如下:

int multibytetowidechar(

uint ucodepage, //標識了與多位元組字串關聯的乙個**值 一般不用 傳0???

dword dwflags, //允許我們額外的控制,它會影響帶變音符號(比如重音) 一般不用 傳0

pcstr pmultibytestr, // 源多位元組字串

int cbmulitbyte, //源多位元組字串的長度(字元) 如果傳進-1,函式便可以自動判斷源串長度

pwstr pwidecharstr, //轉換後的串的指標 即緩衝區的首位址

int cchwidechar ); //指定這個緩衝區的最大長度(字元數),如果傳入0,則函式不會轉換,而是返回乙個寬字元數(包括終止字元'\0'),只有當緩衝區能夠容納該數量的寬字元時,轉換才會成功。

1: 以下為將乙個多位元組串轉化成unicode形式的步驟:

(1)、呼叫multibytetowidechar,為pwidecharstr傳入null,為cchwidechar傳入0,為pmultibytestr傳入-1

(2)、假設上次呼叫的返回值為n ,開闢一塊緩衝區,大小為 n *sizeof( wchar_t)

(3)、再呼叫一次multibytetowidechar,pwidecharstr為開闢的緩衝區的首位址,cchwidechar 為n

(4)、使用轉換後的字串

(5)、釋放緩衝區

**: char str1[100] = "1234567890";

int numchar = ::multibytetowidechar(0,0,str1,-1,null,0);

wchar_t *str2 = (wchar_t*)malloc( numchar*sizeof(wchar_t) );

::multibytetowidechar(0,0,str1,-1,str2,numchar);

::wprintf_s(str2);

2:unicode轉換為多位元組字串:

int widechartomultibyte(

uint ncodepage, //標識了與多位元組字串關聯的乙個**值 一般不用 傳0???

dword dwflags, //允許我們額外的控制,它會影響帶變音符號(比如重音) 一般不用 傳0

pcwstr pwidecharstr,//源unicode字串

int cchwidechar, //unicode字元數

pstr pmultibytestr, //緩衝區首位址

int cbmultibyte, //緩衝區最大的長度 防止溢位

pcstr pdefaultchar,//當有乙個字元不能轉換時,用該指標指向那個不能轉換的字元

pbool pfuesddefultchar) ;//如果成功轉換 該值為false 如果有至少乙個字元不能成功轉換,該值為ture

用該值來檢測能否轉化成功,

最後這兩個引數只有在碰到有乙個字元不能轉化時才用到,一般傳值null

使用步驟和多位元組轉化為unicode差不多,不同的是第一次呼叫時返回直接就是所需緩衝區的大小(位元組數)!!!

**: wchar_t str1[100] = l"1234567890";

int numchar = ::widechartomultibyte(0,0,str1,-1,null,0,null,null);

char *str2 = (char*)malloc( numchar );

::widechartomultibyte(0,0,str1,-1,str2,numchar,null,null);

printf(str2);

free(str2);

這是寫的乙個小例子:

#include

#include

int main()

結果:? ab

沒有經過轉化的wchar型別和char型別不能這樣強制轉換

#include

#include

int main()

結果:ab ab

成功將char轉化成wchar型別。

wchar和char的區別:

首先,說下窄字元char了,大家都很清楚,就是8bit表示的byte,長度固定。char字元只能表示asii碼表中的256個字元,包括前128個可見字元和後面的128個不可見字元。

而wchar_t則是因為char所能表示的字元數太少(256個)而應運而生的,它的長度可以8bit,16bit,32bit,長度是與不同平台上的c庫相關的。其實這個長度是根據指定平台上想要用的encoding編碼方式來設定的。

在win32 msvc環境下,c庫中wchar_t的長度是2個byte,定義如下:

typedef unsigned short wchar_t; /* 16 bits */

它是按照utf-16編碼,但是因為wchar_t定義的長度只有2個位元組,所以它不能表示utf-16編碼長度為4個位元組的字元。即wchar_t只表示了utf-16的乙個子集。換句話話說,就是msvc下,wchar_t是utf-16編碼的,但是只能表示utf-16的乙個子集。按utf-16編碼時,大部分字元都以固定長度的位元組 (2位元組) 儲存.

在linux-x86的gcc環境下,c庫中wchar_t的長度為四個位元組,用ucs-4(即utf-32編碼方式)。

wchar_t就是儲存的字元的unicode碼值的編碼值,如windows下就是unicode碼值的utf-16編碼值:

tchar wide = l"態";

在vs中watch為: [0] 24577 l'態' wchar_t,即對應的十進位制為24577,而"態"unicode表中查到的碼值為十六進製制的6001,而0x6001對應的十進位制值就是24577.

tchar wide = l"a"; 因為a的unicode值與ascii值一樣,為97. 如果unicode碼值u小於0x10000,則u的utf-16編碼就是u對應的16位無符號整數。

所以可知,0x6001的utf-16編碼值就是0x6001。

wchar_t w1= l'中'; //unicode 編碼

wchar_t w2= '中'; //ansi編碼

printf( "%0x %0x ",w1,w2);

結果:4e2d d6d0

雖然同樣是賦值給wchar_t,但是不同的編碼則值是不同的。同時也說明了wchar_t不光是可以儲存unicode寬字元,也可以儲存其它的編碼。但是如果是儲存的ansi編碼,則按照寬字元的格式輸出的是什麼呢?

wchar_t c= l'中';

wcout.imbue(locale("chs"));

wcout《雖然從網上使用了這種轉化的辦法,但是在自己函式上實現的過程中,還是遇到了問題:就是轉化之後還是出現了亂碼。

這是我函式中接收wchar字串,並且將wchar字串顯示在文字框中的函式:

vsetobjecttext(id_static_serialdata,cgnbasedlg::serialdata);

vsetobjecttext(id_static_mainctrl_ver,s_stcmainctrlver.wmainctrl);

而後來才發現vsetobjecttext()函式的第二個引數應該接收的是乙個全域性變數,而之前我在轉化之前定義的都是靜態的變數,所以才導致雖然多次寫入到檔案的s_stcserialdata.serialdata能讀取到正確的字串,但是在文字框中卻出現亂碼的情況。

0916wchar與char的相互轉化

方法一,使用 bstr t 轉換。include youwill need this const wchar wc l hello world bstr t b wc const char c b printf output s n c 方法二,使用 conversion macros 包含在標頭檔...

char 和char 的區別

1 char是乙個陣列定義,char 是指標定義 也稱char為靜態陣列,char 為動態陣列 2 指標和陣列的區別 1 指標和陣列的分配 陣列是開闢一塊連續的記憶體空間,陣列本身的識別符號 也就是通常所說的陣列名 代表整個陣列,可以使用sizeof來獲得陣列所佔據記憶體空間的大小 注意,不是陣列元...

char 和char 的區別

char c abc c 0 t char c1 def c1 0 t err 首先c1是乙個指標,它只是指向 def 這個記憶體塊。而 abc 是乙個常量區,不可以對其進行更改。而c定義的是乙個陣列,在分配記憶體時,會自動給它分配四個位元組的位址,並且會進行乙份拷貝工作,此時分配是在棧區進行的,是...