c++的gcvt s unicodee编码格式中有gcvt相似的函数吗

编程(32)
本文摘自主页的一篇内容,原文地址:&&
文档在线看:
这份文档简要的说明了如何修改你的C/C++代码使之支持Unicode。在这里并不准备解释太多相关的技术细节并且我得假定你已经基本熟悉Microsoft支持Unicode的方式。它的主要目的是方便你查询相关的数据类型和函数,以及修正相应的拼写错误。
使你的C/C++代码支持Unicode的第一步
定义宏 _UNICODE, 如果定义了宏
_MBCS 则取消它的定义(undefine)。在字符串前添加 L 标记或者用
_T宏修饰字符串。使用 Wide 或者 TCHAR 版本的字符串处理函数。确定API中的字符串长度是按字节计数还是按字符个数计数。因为基于字符的显示和打印(与此不同的是,GUI是基于像素的)使用列数,而不是字节数或者字符个数。在字符串指针相关的计算中使用GetNext格式,因为一个字符可能包含多于一个Unicode字符单元。注意缓冲区的大小以及防止缓冲区溢出。
改变编码方式可能需要增大缓冲区或者限制字符串的最大长度。假设单个字符的大小从1个字节变为4个字节,并且字符串本来20个字符占用20字节,那么你需要将字符串缓冲区扩大为80字节或者将字符串长度限制为5个字符(字符串缓 冲区仍为20字节)。注意缓冲区的扩大可能被限制到一个最大值(比如65KB)。减少字符串长度到一个固定值可能破坏现有的程序,限制字符串长度到固定 值可能是危险的。比如,限制到20字节,将字符串转化为大写形式就可能导致字符串变长并且超过限制。
将接受或者返回单字符参数的函数替换为使用字符串的版本。 (在一些语言中) 对于单个字符的操作可能导致返回多个代码点。例如,upper('ss')将返回&SS&。
使用 wmain 代替 main。环境变量也由_environ变为_wenviron 。
wmain(int argc, wchar_t *argv[], wchar_t *envp[])
MFC Unicode 程序使用& wWinMain 作为程序入口点(VC++ 6.0)。
project-&settings-&Link,选择output选项卡
在Entry point symbol一行加上&wWinMainCRTStartup 。字体的因素,分清使用的字体用于渲染各种语言的字符还是用于脚本中。
文件 I/O, 数据库, 传输协议等因素
考虑是否需要读写文件、数据库中的 UTF-8 或者 UTF-16 字符,以及是否进行数据交换。考虑 UTF-16 格式文件中的字节序。
读写网络传输的数据总是使用 Big-Endian ,如果你没有产生 BOM 也使用 Big-Endian。
文件的字节序依赖于文件格式以及/或者源/目标机器的体系结构。
读取 UTF-16 或者 UTF-32编码的文件时,考虑是否需要将字符按字节逆序。
对于 streams 和传输协议也需要做上述的考虑。 传输协议和用于数据交换的文件要使用正确的编码方式。例如 HTTP,HTML,XML 必须设置为 UTF-8 或者 UTF-16。考虑Unicode字节序标记( BOM ,Byte Order Marker) 以及是否需要将它同数据一同写入。读取数据时记得去掉BOM。考虑遗留数据和文件的编码惯例,考虑导入和导出以及传输协议。(,
) 考虑复制文本到剪贴板
使用 CF_TEXT 格式并且写入本地编码的文本(ANSI格式)
使用 CF_UNICODETEXT 格式并写入Unicode文本数据库程序需要考虑数据类型 (NCHAR,
NVARCHAR) 和模式(schema)的变更,触发器,存储过程和查询,数据的增长,索引以及性能等因素。
注意:Unicode模式的改变对于不同厂商的数据库产生不同的影响。如果需要数据库具有较好的可移植性,就要考虑到 每种数据库的特性和行为。
(我知道针对这个问题说得不够多,以后有机会再补充吧)
如果你使用Microsoft C++编译器,你可能遇到与流式 I/O相关的3类问题:
不支持Unicode文件名。
解决方式是使用 FILE * _wfopen 函数,之后使用FILE句柄初始化流式 I/O。
std::ifstream stm(_wfopen(pFilename, L&r&));
在 读/写 的时候,流式 I/O 会把数据从本地代码页(ANSI格式)转换到Unicode格式/从Unicode格式转换到ANSI格式,而非UTF-8 或者 UTF-16。
但是可以修改表示流的类使之支持读写 UTF-8 格式字符。你可以自己实现一个读写时把数据在 Unicode 和 UTF-8 之间转换的I/O stream类。
codecvt &wchar_t, char_traits &wchar_t& &
如果要用流式 I/O读写 UTF-16 字符,应该用二进制模式打开并且在二进制模式下输入输出。可以用如下方法设 置 I/O 为二进制模式:
_setmode( _fileno( stdin ), _O_BINARY );
也可以参考 Microsoft 运行时库参考: &Unicode Stream I/O in Text and Binary Modes&.
注意:针对cout/wcout,
cin/wcin等并没有相应的 TCHAR 版本。如果你需要在ANSI/Unicode两种模式下编译代码,你可能需要自己定义一个名字类似&tout&的宏。
国际化,Unicode高级技术,平台和其它因素
考虑使用基于地区的办法和更进一步的国际化。对于 Windows 95,98 和 Windiws ME,考虑使用 Microsoft MSLU (Microsoft Layer for Unicode)考虑字符串比较和排序,考虑 考虑 重新考虑是否要自己处理这些事情。借助于一家,然后让你的团队集中精力做他们擅长的事情。(嗨,我们也要谋生啊...)
Unicode字节序标记(BOM) 值
BOM值
(big-endian)
(little-endian)
UTF-16BE, UTF-32BE
(big-endian)
UTF-16LE, UTF-32LE
(little-endian)
(big-endian)
<td style="color:#ff FE FF
(little-endian)
FF FE 00 00
(compression)
U &#43;FEFF。(它也能表示一个被称作 Zero Width No-break Space 的字符)。U&#43;FFFE 这个代码点在Unicode中是非法的,它永远不应该出现在一个Unicode字符流中。所以BOM可以作为放置于文件(或者一 个字符串)的起始作为字节序的指示器。对UTF-16编码而言,如果第一个字符的&#20540;是FE
FF 那么文本和读取文本的机器有相同的字节序。如果是 FF FE,那么有相反的字节序并且需要对每个16-bit字按字节逆序。同样的,BOM指示了UTF-32编码的文本的字节序。
注意不是所有的文件都以Unicode字节序标记开始。事实上,Unicode标准称若不以Unicode字节序标记 (BOM)开始(数据)就必须被表示成big-endian形式。
字符 U&#43;FEFF 同样作为不同Unicode编码方式的标记。左边的表&#26684;说明了
U&#43;FEFF 在每一种Unicode编码方式中的&#20540;。注意:按照定义,标记为UTF-16BE, UTF-32BE, UTF-32LE or UTF-16LE 的文本不应该有BOM,字节序已经由标记本身指出了。
(Standard Compression Scheme for Unicode) 算法压缩过的文本,也有一个推荐的签名。
常量和全局变量
宽字符版本
宏定义版本(TCHAR)
宽字符版本
宏定义版本(TCHAR)
_finddata_t
_wfinddata_t
_tfinddata_t
__finddata64_t
__wfinddata64_t
_tfinddata64_t
_finddatai64_t
_wfinddatai64_t
_tfinddatai64_t
signed char
unsigned char
_T 或者 _TEXT
(wchar_t *)
(_TCHAR *)
(const char *)
(const wchar_t *)
(const _TCHAR *)
Platform SDK字符串处理API
有很多Windows API函数会根据宏 UNICODE 是否被定义而编译成不同形式。那些需要同时操作ANSI字符和宽字符的模块需要了解这一点。否则,应该使用宏定义版 本的名字,这样的话就只需要定义宏
UNICODE 并且重新编译程序。
下列列表并没有列举所有的有ANSI和宽字符两个版本的API,只列举了与字符和字符串处理相关的一些。如果需要 查看与代码页和地区相关的API请查看WinNLS.h头文件。
宽字符版本
宏定义版本(TCHAR)
CharLowerA
CharLowerW
CharLowerBuffA
CharLowerBuffW
CharLowerBuff
CharNextExA
CharNextExW
CharNextEx
CharPrevExA
CharPrevExW
CharPrevEx
CharToOemA
CharToOemW
CharToOemBuffA
CharToOemBuffW
CharToOemBuff
CharUpperA
CharUpperW
CharUpperBuffA
CharUpperBuffW
CharUpperBuff
CompareStringA
CompareStringW
CompareString
FoldStringA
FoldStringW
FoldString
GetStringTypeA
GetStringTypeW
GetStringType
GetStringTypeExA
GetStringTypeExW
GetStringTypeEx
IsCharAlphaA
IsCharAlphaW
IsCharAlpha
IsCharAlphaNumericA
IsCharAlphaNumericW
IsCharAlphaNumeric
IsCharLowerA
IsCharLowerW
IsCharLower
IsCharUpperA
IsCharUpperW
IsCharUpper
LoadStringA
LoadStringW
LoadString
OemToCharA
OemToCharW
OemToCharBuffA
OemToCharBuffW
OemToCharBuff
wvsprintfA
wvsprintfW
CRT字符串处理API
函数按照ANSI版本的ASCII字母顺序排序,方便转换到相应的Unicode版本。
宽字符版本
宏定义版本(TCHAR)
_fgetwchar
_fgettchar
_findfirst
_wfindfirst
_tfindfirst
_findnext64
_wfindnext64
_tfindnext64
_wfindnext
_tfindnext
_findnexti64
_wfindnexti64
_tfindnexti64
_fputwchar
_fputtchar
_wfullpath
_tfullpath
_wmakepath
_tmakepath
_scwprintf
_sctprintf
_searchenv
_wsearchenv
_tsearchenv
_snwprintf
_sntprintf
_wspawnlpe
_tspawnlpe
_wspawnvpe
_tspawnvpe
_splitpath
_wsplitpath
_tsplitpath
_tcsnccoll
_tcsncicmp
_strnicoll
_wcsnicoll
_tcsncicoll
_strnicoll
_wcsnicoll
_tcsnicoll
_strtoui64
_wcstoui64
_tcstoui64
_vscprintf
_vscwprintf
_vsctprintf
_vsnprintf
_vsnwprintf
_vsntprintf
映射为宏或者inline 函数
映射为宏或者inline 函数
映射为宏或者inline 函数
islead (总是返回FALSE)
(总是返回FALSE)
isleadbyte (总是返回FALSE)
isleadbyte (总是返回FALSE)
_istleadbyte
islegal (总是返回TRUE)
(总是返回TRUE)
_istxdigit
_wsetlocale
_tsetlocale
_vftprintf
_vstprintf
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:218873次
积分:2627
积分:2627
排名:第10752名
原创:12篇
转载:347篇
(11)(11)(186)(4)(16)(7)(125)C++/C(26)
一直都觉得C&#43;&#43;对Unicode编码的处理比较麻烦,现就个人经验对这一方面做个总结。
Unicode编码
&& 在领域中,Unicode(统一码、万国码、单一码、标准万国码)是业界的一种标准,它可以使电脑得以呈现世界上数十种文字的系统。Unicode是基于(Universal
Character Set)的标准来发展,并且同时也以书本的形式(The Unicode Standard,目前第五版由Addison-Wesley Professional出版,ISBN-10: )对外发表。Unicode包含了超过十万个(在,Unicode的第十万个字符被采纳且认可成为标准之一)、一组可用以作为视觉参考的代码图表、一套编码方法与一组标准、一套包含了上标字、下标字等字符特性的列举等。
&&&&Unicode的编码方式与的(Universal
Character Set,UCS)概念相对应,目前实际应用的Unicode版本对应于,使用16的编码空间。也就是每个字符占用2个。这样理论上一共最多可以表示216即65536个字符。基本满足各种语言的使用。实际上目前版本的Unicode尚未填充满这16位编码,保留了大量空间作为特殊使用或将来扩展。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&(from wiki)
&&& Unicode是一个标准。UTF-8是其概念上的子集,UTF-8是具体的编码标准。而Unicode是所有想达到
世界统一编码标准的标准。UTF-8标准就是Unicode(ISO10646)标准的一种变形方式,&
UTF的全称是:Unicode/UCS Transformation Format,其实有两种UTF,一种是UTF-8,一种是UTF-16,&
不过UTF-16使用较少,其对应关系如下:
在Unicode中编码为 0000 - 007F 的 UTF-8 中编码形式为: 0xxxxxxx&
在Unicode中编码为 0080 - 07FF 的 UTF-8 中编码形式为: 110xxxxx 10xxxxxx
在Unicode中编码为 0000 - 007F 的 UTF-8 中编码形式为: 1110xxxx 10xxxxxx 10xxxxxx
utf-8是unicode的一个新的编码标准,其实unicode有过好几个标准.我们知道一直以来使用的unicode字符内码都是16位,它实际上还不能把全世界的所有字符编在一个平面系统,比如中国的藏文等小语种,所以utf-8扩展到了32位,也就是说理论在utf-8中可容纳二的三十二次方个字符. UNICODE的思想就是想把所有的字符统一编码,实现一个统一的标准.big5、gb都是独立的字符集,这也叫做远东字符集,把它拿到德文版的WINDOWS上可能将会引起字符编码的冲突....
早期的WINDOWS默认的字符集是ANSI.notepad中输入的汉字是本地编码,但在NT/2000内部是可以直接支持UNICODE的。notepad.exe在WIN95和98中都是ANSI字符,在NT中则是UNICODE.ANSI和UNICODE可以方便的实现对应映射,也就是转换 ASCII是8位范围内的字符集,对于范围之外的字符如汉字它是无法表达的。unicode是16位范围内的字符集,对于不同地区的字符分区分配,unicode是多个IT巨头共同制定的字符编码标准。如果在unicode环境下比如WINDOWS
NT上,一个字符占两字节16位,而在ANSI环境下如WINDOWS98下一个字符占一个字节8位.Unicode字符是16位宽,最多允许65,535字符,数据类型被称为WCHAR。&
对于已有的ANSI字符,unicode简单的将其扩展为16位:比如ANSI&A&=0x43,则对应的UNICODE为
&A&= 0x0043
而ASCII用七存放128个字符,ASCII是一个真正的美国标准,所以它不能满足其他国家的需要,例如斯拉夫语的
字母和汉字于是出现了Windows ANSI字符集,是一种扩展的ASCII码,用8位存放字符,低128位仍然存放原来的ASCII码, 而高128位加入了希腊字母等
if def UNICODE
& TCHAR = wchar
& TCHAR = char
你需要在Project\Settings\C/C&#43;&#43;\Preprocesser definitions中添加UNICODE和_UNICODE&
UINCODE,_UNICODE都要定义。不定义_UNICODE的话,用SetText(HWND,LPCTSTR),将被解释为SetTextA
(HWND,LPTSTR),这时API将把你给的Unicode字符串看作ANSI字符串,显示乱码。因为windows API是已经编译好存在于dll中的,由于不管UNICODE还是ANSI字符串,都被看作一段buffer,如&0B A3 00 35 24 3C 00 00&如果按ANSI读,因为ANSI字串是以'\0'结束的,所以只能读到两字节&0B A3 \0&,如果按UNICODE读,将完整的读到'\0\0'结束。
由于UNICODE没有额外的指示位,所以系统必须知道你提供的字串是哪种&#26684;式。此外,UNICODE好象是ANSI
C&#43;&#43;规定的,_UNICODE是windows SDK提供的。如果不编写windows程序,可以只定义UNICODE。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&(from WINODWS编码)
有关C&#43;&#43;处理:
& 在使用标标准C&#43;&#43;编程时,其默认的编码方式是基于ANSCI。特别在处理文本数据时,一般常用的读写函数及字符处理都是用来处理ANSCII编码方式的,如:
&& 当然为了处理Unicode编码C&#43;&#43;为每个字符处理函数提供了宽字符(wchar_t)处理函数。但实际使用这些完字符函数进行字符读写时达不到想要的结果,经常会出现乱码。所以在实际使用时一直都没法用上这些所谓的宽字符处理函数。为了达到目的,只要采用更加底层的C语言文件读写函数,以二进制的方式进行处理,如:
&& 举一个例子,我们需要将一个ANSCII码的文件转换为对应的Unicode文件,使用C&#43;&#43;进行转换处理:
设输入文件:input.txt
& 输出文件:output.txt
以如下方式打开这两个文件:
&input.open(sfile);//打开输入文件
&output=_wfopen(dfile,L&wb&);//以宽字符模式打开输出文件
&if(!output)
&&cout&&&Can't open the output file:&&&dfile&&
&&exit(1);
&fwrite(L&\xFEFF&,sizeof(wchar_t),1,output);//向输出文件写入UNICODE文件的开始标志
&if(!input)
&&cout&&&Can't open the input file:&&&sfile&&
&&exit(1);
当将ANSCI编码的文件input读出来时,对其中的英文字符可以直接转换为宽字符而不会产生乱码:
outUnic[j]=wchar_t(inget[k])//inget[k]为ANSCI的英文字符,outUnic为其对应的UNICODE字符
对input中的中文字符,则不能直接转换,这样会出现乱码。对其中的中文字符需要使用Windows的API函数将中文内码转换为对应的Unicode编码:
//假设inget[i]和inget[i&#43;1]中存有一个中文字符
&& char p[2];
&&&wchar_t tUni[1];
&&&p[0]=inget[i];p[1]=inget[i&#43;1];
&&&MultiByteToWideChar(CP_ACP,0,p,-1,tUni,1);//调用windows的API函数将中文内码转换成& UNICODE码
这个函数的具体参数可以查询MSDN,其功能为将多字符转换为宽字符,还对应有一个将宽字节转换为多字节的函数。
&&&outUnic[j&#43;&#43;]=tUni[0];//tUni中为转换好的中文Unicode内码
当将读出的字符串转换为对应的Unicode字符串后,可按如下方式写入到output.txt 文件中:
fwrite( outUnic, sizeof( wchar_t), wstrlen(outUnic), output);
以上即为一个简单的C&#43;&#43;对Unicode编码的处理,其过程远不如其它语言如java简洁。可能这也是C&#43;&#43;的特色之处。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:319334次
积分:3749
积分:3749
排名:第6553名
原创:85篇
转载:62篇
评论:42条
阅读:10156
(1)(2)(5)(7)(1)(1)(4)(2)(1)(1)(8)(19)(13)(6)(3)(6)(7)(13)(5)(1)(2)(1)(1)(17)(20)c++string如何读取在文本中的unicode编码 - 开源中国社区
当前访客身份:游客 [
当前位置:
c++string如何读取在文本中的unicode编码,比如读取文本中的\u6C49\u5B57,解析成“汉字”,而不是解析成字符串。本人用原生c++,不依赖微软的库和WindowsAPI。对能给出正解的人万分感谢!
共有8个答案
<span class="a_vote_num" id="a_vote_num_
不依赖微软的库和WindowsAPI,没能试验成功!
--- 共有 1 条评论 ---
问题已解决,谢谢。
(4年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
看这篇文章,讲的很清楚(:)这是从其他地方拷贝过来的)
UNICODE环境设置
在安装Visual Studio时,在选择VC++时需要加入unicode选项,保证相关的库文件可以拷贝到system32下。
UNICODE编译设置:
C/C++, Preprocessor difinitions 去除_MBCS,加_UNICODE,UNICODE
在ProjectSetting/link/output 中设置Entry为wWinMainCRTStartup
反之为MBCS(ANSI)编译。
Unicode :宽字节字符集
1. 如何取得一个既包含单字节字符又包含双字节字符的字符串的字符个数?
可以调用Microsoft Visual C++的运行期库包含函数_mbslen来操作多字节(既包括单字节也包括双字节)字符串。
调用strlen函数,无法真正了解字符串中究竟有多少字符,它只能告诉你到达结尾的0之前有多少个字节。
size_t strlen( const char *string );
size_t wcslen( const wchar_t *string );
size_t _mbslen( const unsigned char *string );
size_t _mbstrlen( const char *string );
2. 如何对DBCS(双字节字符集)字符串进行操作?
PTSTR CharNext ( LPCTSTR ); 返回字符串中下一个字符的地址
PTSTR CharPrev ( LPCTSTR, LPCTSTR ); 返回字符串中上一个字符的地址
BOOL IsDBCSLeadByte( BYTE ); 如果该字节是DBCS字符的第一个字节,则返回非0值
3. 为什幺要使用Unicode?
(1) 可以很容易地在不同语言之间进行数据交换。
(2) 使你能够分配支持所有语言的单个二进制.exe文件或DLL文件。
(3) 提高应用程序的运行效率。
Windows 2000是使用Unicode从头进行开发的,如果调用任何一个Windows函数并给它传递一个ANSI字符串,那幺系统首先要将字符串转换成Unicode,然后将Unicode字符串传递给操作系统。如果希望函数返回ANSI字符串,系统就会首先将Unicode字符串转换成ANSI字符串,然后将结果返回给你的应用程序。进行这些字符串的转换需要占用系统的时间和内存。通过从头开始用Unicode来开发应用程序,就能够使你的应用程序更加有效地运行。
Windows CE 本身就是使用Unicode的一种操作系统,完全不支持ANSI Windows函数
Windows 98 只支持ANSI,只能为ANSI开发应用程序。
Microsoft公司将COM从16位Windows转换成Win32时,公司决定需要字符串的所有COM接口方法都只能接受Unicode字符串。
4. 如何编写Unicode源代码?
& Microsoft公司为Unicode设计了WindowsAPI,这样,可以尽量减少代码的影响。实际上,可以编写单个源代码文件,以便使用或者不使用Unicode来对它进行编译。只需要定义两个宏(UNICODE和_UNICODE),就可以修改然后重新编译该源文件。
& _UNICODE宏用于C运行期头文件,而UNICODE宏则用于Windows头文件。当编译源代码模块时,通常必须同时定义这两个宏。
& 5. Windows定义的Unicode数据类型有哪些?
& 数据类型 说明
& WCHAR Unicode字符
& PWSTR 指向Unicode字符串的指针
& PCWSTR 指向一个恒定的Unicode字符串的指针
& 对应的ANSI数据类型为CHAR,LPSTR和LPCSTR。
& ANSI/Unicode通用数据类型为TCHAR,PTSTR,LPCTSTR。
& 6. 如何对Unicode进行操作?
& 字符集 特性 实例
& ANSI 操作函数以str开头 strcpy
& Unicode 操作函数以wcs开头 wcscpy
& MBCS 操作函数以_mbs开头 _mbscpy
& ANSI/Unicode 操作函数以_tcs开头 _tcscpy(C运行期库)
& ANSI/Unicode 操作函数以lstr开头 lstrcpy(Windows函数)
& 所有新的和未过时的函数在Windows2000中都同时拥有ANSI和Unicode两个版本。ANSI版本函数结尾以A表示;Unicode版本函数结尾以W表示。Windows会如下定义:
& #ifdef UNICODE
& #define CreateWindowEx CreateWindowExW
& #define CreateWindowEx CreateWindowExA
& #endif // !UNICODE
& 7. 如何表示Unicode字符串常量?
& 字符集 实例
& ANSI “string”
& Unicode L“string”
& ANSI/Unicode T(“string”)或_TEXT(“string”)
& if( szError[0] == _TEXT(‘J’) ){ }
& 8. 为什幺应当尽量使用操作系统函数?
& 这将有助于稍稍提高应用程序的运行性能,因为操作系统字符串函数常常被大型应用程序比如操作系统的外壳进程Explorer.exe所使用。由于这些函数使用得很多,因此,在应用程序运行时,它们可能已经被装入RAM。
& 如:StrCat,StrChr,StrCmp和StrCpy等。
& 9. 如何编写符合ANSI和Unicode的应用程序?
& (1) 将文本串视为字符数组,而不是chars数组或字节数组。
& (2) 将通用数据类型(如TCHAR和PTSTR)用于文本字符和字符串。
& (3) 将显式数据类型(如BYTE和PBYTE)用于字节、字节指针和数据缓存。
& (4) 将TEXT宏用于原义字符和字符串。
& (5) 执行全局性替换(例如用PTSTR替换PSTR)。
& (6) 修改字符串运算问题。例如函数通常希望在字符中传递一个缓存的大小,而不是字节。这意味着不应该传递sizeof(szBuffer),而应该传递(sizeof(szBuffer)/sizeof(TCHAR)。另外,如果需要为字符串分配一个内存块,并且拥有该字符串中的字符数目,那幺请记住要按字节来分配内存。这就是说,应该调用
& malloc(nCharacters *sizeof(TCHAR)),而不是调用malloc(nCharacters)。
& 10. 如何对字符串进行有选择的比较?
& 通过调用CompareString来实现。
& int CompareString(
&& LCID Locale, // locale identifier
DWORD dwCmpFlags, // comparison-style options
LPCTSTR lpString1, // pointer to first string
int cchCount1, // size, in bytes or characters, of first string
LPCTSTR lpString2, // pointer to second string
int cchCount2 // size, in bytes or characters, of second string
Locale 本地比较的定义
&& LOCALE_USER_DEFAULT
&& LOCALE_SYSTEM_DEFAULT
& 标志 含义
& NORM_IGNORECASE 忽略字母的大小写
& NORM_IGNOREKANATYPE 不区分平假名与片假名字符
& NORM_IGNORENONSPACE 忽略无间隔字符
& NORM_IGNORESYMBOLS 忽略符号
& NORM_IGNOREWIDTH 不区分单字节字符与作为双字节字符的同一个字符
& SORT_STRINGSORT 将标点符号作为普通符号来处理
& 11. 如何判断一个文本文件是ANSI还是Unicode?
& 判断如果文本文件的开头两个字节是0xFF和0xFE,那幺就是Unicode,否则是ANSI。
& 12. 如何判断一段字符串是ANSI还是Unicode?
& 用IsTextUnicode进行判断。IsTextUnicode使用一系列统计方法和定性方法,以便猜测缓存的内容。由于这不是一种确切的科学方法,因此 IsTextUnicode有可能返回不正确的结果。
& 13. 如何在Unicode与ANSI之间转换字符串?
& Windows函数MultiByteToWideChar用于将多字节字符串转换成宽字符串;函数WideCharToMultiByte将宽字符串转换成等价的多字节字符串。
& 14. Unicode和DBCS之间的区别
&& Unicode使用(特别在C程序设计语言环境里)“宽字符集”。「Unicode中的每个字符都是16位宽而不是8位宽。」在Unicode中,没有单单使用8位数值的意义存在。相比之下,在“双位组字符集”中我们仍然处理8位数值。有些位组自身定义字符,而某些位组则显示需要和另一个位组共同定义一个字符。
&&& 处理DBCS字符串非常杂乱,但是处理Unicode文字则像处理有秩序的文字。您也许会高兴地知道前128个Unicode字符(16位代码从0xF)就是ASCII字符,而接下来的128个Unicode字符(代码从0xFF)是ISO 8859-1对ASCII的扩展。Unicode中不同部分的字符都同样基于现有的标准。这是为了便于转换。希腊字母表使用从0xFF的代码,斯拉夫语使用从0xFF的代码,美国使用从0xF的代码,希伯来语使用从0xFF的代码。中国、日本和韩国的象形文字(总称为CJK)占用了从0xFFF的代码。Unicode的最大好处是这里只有一个字符集,没有一点含糊。
&&& 15.衍生标准
&&& Unicode是一个标准。UTF-8是其概念上的子集,UTF-8是具体的编码标准。而UNICODE是所有想达到世界统一编码标准的标准。UTF-8标准就是Unicode(ISO10646)标准的一种变形方式,
&&&& UTF的全称是:Unicode/UCS Transformation Format,其实有两种UTF,一种是UTF-8,一种是UTF-16,
&&&& 不过UTF-16使用较少,其对应关系如下:
&&&& 在Unicode中编码为 0000 - 007F 的 UTF-8 中编码形式为: 0xxxxxxx
&&&& 在Unicode中编码为 0080 - 07FF 的 UTF-8 中编码形式为: 110xxxxx 10xxxxxx
&&&& 在Unicode中编码为 0000 - 007F 的 UTF-8 中编码形式为: 1110xxxx 10xxxxxx 10xxxxxx
&&&& utf-8是unicode的一个新的编码标准,其实unicode有过好几个标准.我们知道一直以来使用的unicode字符内码都是16位,它实际上还不能把全世界的所有字符编在一个平面系统,比如中国的藏文等小语种,所以utf-8扩展到了32位,也就是说理论在utf-8中可容纳二的三十二次方个字符. UNICODE的思想就是想把所有的字符统一编码,实现一个统一的标准.big5、gb都是独立的字符集,这也叫做远东字符集,把它拿到德文版的WINDOWS上可能将会引起字符编码的冲突....早期的WINDOWS默认的字符集是ANSI.notepad中输入的汉字是本地编码,但在NT/2000内部是可以直接支持UNICODE的。notepad.exe在WIN95和98中都是ANSI字符,在NT中则是UNICODE.ANSI和UNICODE可以方便的实现对应映射,也就是转换 ASCII是8位范围内的字符集,对于范围之外的字符如汉字它是无法表达的。unicode是16位范围内的字符集,对于不同地区的字符分区分配,unicode是多个IT巨头共同制定的字符编码标准。如果在unicode环境下比如WINDOWS NT上,一个字符占两字节16位,而在ANSI环境下如WINDOWS98下一个字符占一个字节8位.Unicode字符是16位宽,最多允许65,535字符,数据类型被称为WCHAR。
&&&&& 对于已有的ANSI字符,unicode简单的将其扩展为16位:比如ANSI&A&=0x43,则对应的UNICODE为
&&&&& &A&= 0x0043
&&&&&& 而ASCII用七存放128个字符,ASCII是一个真正的美国标准,所以它不能满足其他国家的需要,例如斯拉夫语的字母和汉字于是出现了Windows ANSI字符集,是一种扩展的ASCII码,用8位存放字符,低128位仍然存放原来的ASCII码,
&&&&&& 而高128位加入了希腊字母等
&&&&&& if def UNICODE
&&&&&& TCHAR = wchar
&&&&&& else
&&&&&& TCHAR = char
&&&&&& 你需要在Project\Settings\C/C++\Preprocesser definitions中添加UNICODE和_UNICODE
&&&&&& UINCODE,_UNICODE都要定义。不定义_UNICODE的话,用SetText(HWND,LPCTSTR),将被解释为SetTextA(HWND,LPTSTR),这时API将把你给的Unicode字符串看作ANSI字符串,显示乱码。因为windows API是已经编译好存在于dll中的,由于不管UNICODE还是ANSI字符串,都被看作一段buffer,如&0B A3 00 35 24 3C 00 00&如果按ANSI读,因为ANSI字串是以'\0'结束的,所以只能读到两字节&0B A3 \0&,如果按UNICODE读,将完整的读到'\0\0'结束。
&&&&&&& 由于UNICODE没有额外的指示位,所以系统必须知道你提供的字串是哪种格式。此外,UNICODE好象是ANSI C++规定的,_UNICODE是windows SDK提供的。如果不编写windows程序,可以只定义UNICODE。
开发过程:
&&&&&&& 围绕着文件读写、字符串处理展开。文件主要有两种:.txt和.ini文件
&&&&&& 在unicode和非unicode环境下字符串做不同处理的,那么需要参考以上9,10两条,以适应不同环境得字符串处理要求。
&&&&&&& 对文件读写也一样。只要调用相关接口函数时,参数中的字符串前都加上_TEXT等相关宏。如果写成的那个文件需要是unicode格式保存的,那么在创建文件时需要加入一个字节头。
&&&&&&&& CF
&&&&&&&&& WCHAR szwBuffer[128];
&&&&&&&&& WCHAR *pszUnicode = L&Unicode string\n&; // unicode string
&&&&&&&&& CHAR *pszAnsi = &Ansi string\n&; // ansi string
&&&&&&&&& WORD wSignature = 0xFEFF;
&&&&&&&&& file.Open(TEXT(&Test.txt&), CFile::modeCreate|CFile::modeWrite);
&&&&&&&&& file.Write(&wSignature, 2);
&&&&&&&&& file.Write(pszUnicode, lstrlenW(pszUnicode) * sizeof(WCHAR));
&&&&&&&&& // explicitly use lstrlenW function
&&&&&&&&& MultiByteToWideChar(CP_ACP, 0, pszAnsi, -1, szwBuffer, 128);
&&&&&&&&& file.Write(szwBuffer, lstrlenW(szwBuffer) * sizeof(WCHAR));
&&&&&&&&&& file.Close();
&&&&&&&&&& //以上这段代码在unicode和非unicode环境下都有效。这里显式的指明用Unicode来进行操作。
&&&&&&&&& 在非unicode环境下,缺省调用的都是ANSI格式的字符串,此时TCHAR转换为CHAR类型的,除非显式定义WCHAR。所以在这个环境下,如果读取unicode文件,那么首先需要移动2个字节,然后读取得字符串需要用MultiByteToWideChar来转换,转换后字符串信息才代表unicode数据。
&&&&&&&& 在unicode环境下,缺省调用得都是unicode格式得字符串,也就是宽字符,此时TCHAR转换为WCHAR,相关得API函数也都调用宽字符类型的函数。此时读取unicode文件也和上面一样,但是读取得数据是WCHAR的,如果要转换成ANSI格式,需要调用WideCharToMultiByte。如果读取ANSI的,则不用移动两个字节,直接读取然后视需要转换即可。
&&&&&&&&& 某些语言(如韩语)必须在unicode环境下才能显示,这种情况下,在非unicode环境下开发,就算用字符串函数转换也不能达到显示文字的目的,因为此时调用得API函数是用ANSI的(虽然底层都是用UNICODE处理但是处理结果是按照程序员调用的API来显示的)。所以必须用unicode来开发。
<span class="a_vote_num" id="a_vote_num_
用WideCharToMultiByte这个API:
#include &windows.h&
int main()
wchar_t utf[1000], *p =
char ansi[2000];
_wfopen(L&C:\\1.txt&, L&rb&);
while(!feof(fp))
fread(p++, 1, 2,
*--p = L'\0';
fclose(fp);
utf+1剔除UTf-16标记
WideCharToMultiByte(CP_ACP, 0, utf + 1, -1, ansi,
sizeof(ansi), NULL, NULL);
puts(ansi);
<span class="a_vote_num" id="a_vote_num_
楼上的给个链接就好,不用大篇幅复制。
卤煮的意思是说把“\u6C49\u5B57” 这个ASCII字符串转成两个汉字对吧~
<span class="a_vote_num" id="a_vote_num_
不用别人的库,查unicode编码表?lz解决了说说方法呀
--- 共有 1 条评论 ---
C++没解决,后来这个模块改用C#写了。
(3年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
按二进制读,先读出0xFF 0xFE,后面数据的两个字节表示一个字,自己想办法读到wstring中
显示,用API的话,一个wcstombs ,一个WideCharToMultiByte
不用API的话自己查表,嵌入式程序可以查表,x86程序完全没那个必要
<span class="a_vote_num" id="a_vote_num_
干嘛不用std::wstring
<span class="a_vote_num" id="a_vote_num_
用std::wstring吧,自己没有试过……,你可以去尝试下
更多开发者职位上
有什么技术问题吗?
类似的话题

我要回帖

更多关于 unicode编码 的文章

 

随机推荐