mbstowcs 和 wcstombs函数:C语言提供的宽字符和多字节字符转换函数
C語言中的多字節字符與寬字符
字符型char只占八位,存儲ascii碼的,而寬字符型是為了存儲多國語言的代碼unicode,包括中文,法語德語什么的,8位256種不夠用了
C語言原本是在英文環境中設計的,主要的字符集是7位的ASCII碼,8位的byte(字節)是最常見的字符編碼單位。但是國際化軟件必須能夠表示不同的字符,而這些字符數量龐大,無法使用一個字節編碼。?
C95標準化了兩種表示大型字符集的方法:寬字符(wide character,該字符集內每個字符使用相同的位長)以及多字節字符(multibyte character,每個字符可以是一到多個字節不等,而某個字節序列的字符值由字符串或流(stream)所在的環境背景決定)。
自從1994年的增補之后,C語言不只提供char類型,還提供wchar_t類型(寬字符),此類型定義在stddef.h 頭文件中。wchar_t指定的寬字節類型足以表示某個實現版本擴展字符集的任何元素。
在多字節字符集中,每個字符的編碼寬度都不等,可以是一個字節,也可以是多個字節。源代碼字符集和運行字符集都可能包含多字節字符。多字節字符可以被用于字符的常量、字符串字面值(string literal)、標識符(identifier)、注釋(comment),以及頭文件。
C語言本身并沒有定義或指定任何編碼集合,或任何字符集(基本源代碼字符集和基本運行字符集除外),而是由其實現指定如何編碼寬字符,以及要支持什么類型的多字節字符編碼機制。
雖然C標準沒有支持Unicode字符集,但是許多實現版本使用Unicode轉換格式UTF-16和UTF-32來處理寬字符。如果遵循Unicode標準,wchar_t類型至少是16或32位長,而wchar_t類型的一個值就代表一個Unicode字符。
UTF-8是一個由Unicode CONsortium(萬國碼聯盟)定義的實現,可以表示Unicode字符集的所有字符。UTF-8字符所使用的空間大小從一個字節到四個字節都有可能。
多字節字符和寬字符(也就是wchar_t)的主要差異在于寬字符占用的字節數目都一樣,而多字節字符的字節數目不等,這樣的表示方式使得多字節字符串比寬字符串更難處理。比方說,即使字符'A'可以用一個字節來表示,但是要在多字節的字符串中找到此字符,就不能使用簡單的字節比對,因為即使在某個位置找到相符合的字節,此字節也不見得是一個字符,它可能是另一個不同字符的一部分。然而,多字節字符相當適合用來將文字存儲成文件。
C提供了一些標準函數,可以將多字節字符轉換為wchar_t,或將寬字符轉換為多字節字符。比方說,如果C 編譯器使用Unicode 標準的UTF-16 和UTF-8,那么下面調用wctomb()函數就可以獲得字符的多字節表示方式(注:wctomb = wide character to multibyte)。
在我們常用的類型string和char中,對中文支持并不是很好。在這兩種類型中,中文都是兩個字節,也就是說中文的漢字要占用兩個位置,舉個簡單的例子,一個“漢”字用一個char是無法表示的,即 ? ?char c = '漢' ; ?是錯誤的,必須用 char c[3] ?= "漢". 漢字占用兩個字節,還有一個結尾符“0/”。string s = "漢" ; s.length()的值是2.?
通過以上描述,我們會發現,我們在進行包含中文字符串處理的過程中就會遇到以下問題:在包含數字,字母,漢字的字符串處理中我們應該怎樣應付各個字符占多少個字節?總不能在處理之前先轉換成ASCII碼判斷它屬于哪種字符在進行處理吧?中文取兩個,字母和數字取一個。在進行判斷相等與否時也遇到了問題。
mbstowcs 和 wcstombs函數:C語言提供的寬字符和多字節字符轉換函數
本文介紹兩個由C語言提供的寬字符(wchar_t類型)和多字節字符( 一個字符用一個或者多個字節表示) 轉換函數,因此具有通用性(在Windows/Linux系統中都可以使用): 所需頭文件:#include <stdlib.h> ( 1 ) mbstowcs() 功能:把多字節字符轉換成寬字符 原型: size_t mbstowcs(wchar_t *wcstr,const char *mbstr,size_t count ); 參數: 1> wcstr 目標緩存,用來存放轉換之后的寬字節字符;當取值為NULL時,返回值為目標緩存所需wchar_t類型的個數 2> mbstr 用來存放待轉換的多字節字符串 3> count 用來指定最多轉換多少Byte。當wcstr取值為NULL時,該值無用 返回值: 轉換成功,且wcstr == NULL時,返回目標緩存所需的大小(wchar_t 類型個數,但不含終結符); 轉換成功,且wcstr != NULL時,返回轉換的字節數; 轉換不成功,返回(size_t) (-1); 使用步驟: 1) 調用mbstowcs()函數,設置參數 wcstr 為NULL(用以獲取轉換所需的接收緩沖區大小); 2) 給目標緩存區分配足夠的內存塊,用于存放轉換后的wchar_t字符串; 注意:該內存塊的大小由首次調用mbstowcs()函數的返回值來決定(該返回值不包含終止符的空間) 3) 再次調用mbstowcs()函數,這次將目標緩存的地址作為 wcstr 參數來傳遞; 代碼示例: [cpp] view plaincopy strcpy(sBuf, "我最棒"); size_t sSize=strlen(sBuf); wchar_t * dBuf=NULL; <SPAN style="COLOR: #ff0000">//注意:需要多分配一個空間,以存放終止符</SPAN> int dSize=mbstowcs(dBuf, sBuf, 0)+1; dBuf=new wchar_t[dSize]; wmemset(dBuf, 0, dSize); int nRet=mbstowcs(dBuf, sBuf, sSize); if(nRet<=0) { printf("轉換失敗\n"); } else { printf("轉換成功%d字符\n", nRet); wprintf(L"%ls\n", dBuf); } [cpp] view plain copy strcpy(sBuf, "我最棒"); size_t sSize=strlen(sBuf); wchar_t * dBuf=NULL; <span style="color:#ff0000;">//注意:需要多分配一個空間,以存放終止符</span> int dSize=mbstowcs(dBuf, sBuf, 0)+1; dBuf=new wchar_t[dSize]; wmemset(dBuf, 0, dSize); int nRet=mbstowcs(dBuf, sBuf, sSize); if(nRet<=0) { printf("轉換失敗\n"); } else { printf("轉換成功%d字符\n", nRet); wprintf(L"%ls\n", dBuf); } ( 2 ) wcstombs() 功能: 把寬字符把轉換成多字節字符串 原型: size_t wcstombs(char *mbstr,const wchar_t *wcstr,size_t count ); 參數: 1> wcstr 目標緩存,用來存放轉換之后的多字節字符;當取值為NULL時,返回值為目標緩存所需wchar_t類型的個數; 2> mbstr 用來存放待轉換的寬字符; 3> count 用來指定接收緩存里能夠存儲的最大的字節數; 返回值: 轉換成功,且mbstr == NULL時,返回目標緩存所需的大小(char 類型個數,但不含終結符); 轉換成功,且mbstr != NULL時,返回轉換的字節數; 轉換不成功,返回(size_t)(-1); 注意:If wcstombs encounters a wide character it cannot be convert to a multibyte character, it returns –1 cast to type size_t. 使用方法: 與mbstowcs()方法類似 示例代碼: [cpp] view plaincopy wchar_t sBuf[20]={0}; wcscpy(sBuf, L"Hello"); size_t sSize=wcslen(sBuf); char * dBuf=NULL; int dSize=wcstombs(dBuf, sBuf, 0)+1; printf("需要%d Char\n", dSize); dBuf=new char[dSize]; memset(dBuf, 0, dSize); int nRet=wcstombs(dBuf, sBuf, dSize); if(nRet<=0) { printf("轉換失敗\n"); } else { printf("轉換成功%d字符\n", nRet); printf("%s\n", dBuf); } [cpp] view plain copy wchar_t sBuf[20]={0}; wcscpy(sBuf, L"Hello"); size_t sSize=wcslen(sBuf); char * dBuf=NULL; int dSize=wcstombs(dBuf, sBuf, 0)+1; printf("需要%d Char\n", dSize); dBuf=new char[dSize]; memset(dBuf, 0, dSize); int nRet=wcstombs(dBuf, sBuf, dSize); if(nRet<=0) { printf("轉換失敗\n"); } else { printf("轉換成功%d字符\n", nRet); printf("%s\n", dBuf); } 上面的代碼在轉換英文的時候沒有問題,在轉換中文時,wcstombs()函數會返回-1 注意: 寬字節,即wchar_t 類型采用Unicode編碼方式,在Windows中為utf-16,在Linux中為utf-32 而多字節則可能是其他很多編碼方式,如utf-8、GB232.... 因此,需要指定多字節編碼類型,才能進行正常的轉換過程。 設置或獲取多字節編碼方式用函數:setlocale() 所需頭文件:locale.h #include <locale.h>總結
以上是生活随笔為你收集整理的mbstowcs 和 wcstombs函数:C语言提供的宽字符和多字节字符转换函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: QT5中实现多窗口切换,并从子窗口返回数
- 下一篇: 三种睡眠时间函数的区别:linux 的s