zoukankan      html  css  js  c++  java
  • Unicode与ANSI(转载)

    一、Unicode与ANSI简介
        1.Unicode与ANSI两种字符编码方式,就是说我们平常所定的字,在计算机中是怎么存储的。美国人所用的英语总共用到26个字符再加0-9,再加上其它一些标点,也不过就128个。而计算机中的一个字节就有8位,共有256种组合(每一位有两种可能(0或1)、一共有8位。结果就是8个2连乘)。所以说对美国人来将所有字符一个字节就够了(计算机是他们发明的,当时当然也没有想外国也要用);好的,一人字节表示英语到还够了,可是我们的汉字,韩国的韩文呢!后来,几个大公司联合起来起草了用2个字节来表示字符的Unicode,2字节有65535种组合,所以对全球的字符都够。
    二、Windows对Unicode的支持
         1、Win98仅支持ANSI
         2、WinCE仅支持Unicode
         3、Win2000支持Unicode,兼容ANSI,也就是所说所有核心程序都是在Unicode下运行的,如果你调用ANSI版本的API,它就所你的内容翻译成Unicode,然后计算,然后将计算结果再转换成ANSI传给你。
    三、Unicode与ANSI之间的转换

    #include "stdafx.h"
    #include <windows.h>
    #include <lm.h>
    #include <stdio.h>

    int _tmain(int argc, _TCHAR* argv[])
    {
     PSTR pStr = {"这量一个ANSI的字串"},pNew;
     
     PWSTR pWideCharStr;
     int nLen;
     BOOL fOk = FALSE;

     //计算ANSI转换成Unicode后需要的字符数
     //其中pStr为ANSI字符串
     nLen = MultiByteToWideChar(CP_ACP, 0, pStr, -1, NULL, 0);
     //分配存放Unicode字串的内存
     pWideCharStr = new WCHAR( nLen * sizeof(WCHAR));
     printf("%d",strlen(pStr));  //18个字符
     //进行转换ANSI---->Unicode;其中nLen指明存放Unicode的内存大小
     MultiByteToWideChar(CP_ACP, 0, pStr, -1, pWideCharStr, nLen);
     //以下是Unicode--->ANSI;其中strlen(...)表示存放ANSI的内存大小
     pNew= new char(15);
     WideCharToMultiByte(CP_ACP, 0, pWideCharStr, -1, pNew, strlen(pNew), NULL, NULL);
     //当分配的内存过小时,会出现字符串截取
     
     //int WideCharToMultiByte(
     //UINT CodePage,            // code page
     //DWORD dwFlags,            // performance and mapping flags
     //LPCWSTR lpWideCharStr,    // wide-character string
     //int cchWideChar,          // number of chars in string.
     //LPSTR lpMultiByteStr,     // buffer for new string
     //int cbMultiByte,          // size of buffer
     //LPCSTR lpDefaultChar,     // default for unmappable chars
     //LPBOOL lpUsedDefaultChar  // set when default char used
     //);
     //int MultiByteToWideChar(
     //  UINT CodePage,         // code page
     //  DWORD dwFlags,         // character-type options
     //  LPCSTR lpMultiByteStr, // string to map
     //  int cbMultiByte,       // number of bytes in string
     //  LPWSTR lpWideCharStr,  // wide-character buffer
     //  int cchWideChar        // size of buffer
     //);
     //当成功返回时,并且参数cchWideChar值为非0时,返回值为写到lpWideCharStr所指的缓冲中的数量
     //当成功返回时,并且参数cchWideChar值为0时,返回的值为所要存放的字符数。
     //当dwFlag = 0,输入的字符串是UTF-8并包含无效字符时,返回 ERROR_NO_UNICODE_TRANSLATION.
     //当函数失败时,返回0,GetLastError如下:
     //ERROR_INSUFFICIENT_BUFFER
     //ERROR_INVALID_FLAGS
     //ERROR_INVALID_PARAMETER
     //ERROR_NO_UNICODE_TRANSLATION
     //汉字占两个字节,全角字符占两个字节,半角占一个字节。
     return 0;
    }
    四、成为符合ANSI和Unicode的应用程序[此段摘自Windows核心编程]

    即使你不打算立即使用Unicode ,最好也应该着手将你的应用程序转换成符合Unicode 的应用程序。下面是应该遵循的一些基本原则:

    • 将文本串视为字符数组,而不是chars数组或字节数组。
    • 将通用数据类型(如TCHAR和PTSTR)用于文本字符和字符串。
    • 将显式数据类型(如BYTE和PBYTE)用于字节、字节指针和数据缓存。
    • 将TEXT宏用于原义字符和字符串。
    • 执行全局性替换(例如用PTSTR替换PSTR)。
    • 修改字符串运算问题。例如函数通常希望你在字符中传递一个缓存的大小,而不是字节。

    这意味着你不应该传递sizeof(szBuffer) ,而应该传递(sizeof(szBuffer) / sizeof( TCHAR)。另外,如果需要为字符串分配一个内存块,并且拥有该字符串中的字符数目,那么请记住要按字节来分配内存。这就是说,应该调用malloc(nCharacters *sizeof(TCHAR)),而不是调用malloc(nCharacters)。在上面所说的所有原则中,这是最难记住的一条原则,如果操作错误,编译器将不发出任何警告。

    当我为本书的第一版编写示例程序时,我编写的原始程序只能编译为ANSI程序。后来,当我开始撰写本章的内容时,我想我应该鼓励使用Unicode ,并且打算创建一些示例程序,以便展示你可以非常容易地编写既可以用Unicode 也可以用ANSI来编译的程序。这时我发现最好的办法是将本书的所有示例程序进行转换,使它们都能够用Unicode 和ANSI进行编译。

    五、其它
        _UNICODE,_TEXT宏都是c运行库中定义的宏。
       UNICODE,TEXT宏是在Windows.h/Winnt.h中定义的。所以当要调用WindowAPI时。如果要编译UNICODE版程序时,要定义UNICODE宏,如果还用到C运行库中对UNICODE的支持时,就应还定义一个_UNICODE宏。也就是说通常都要定义两个宏UNICODE和_UNICODE。
    //摘自<windows 核心编程>
    char szA[100];             //An ANSI string buffer
    WCHAR szW[100];            //A Unicode string buffer

    //Normal sprintf:all strings are ANSI
    sprintf(szA, "%s","ANSI Str");

    //Converts Unicode string to ANSI
    sprintf(szA,"%S",L"Unicode Str");

    //Normal swprintf:all strings are Unicode
    swprintf(szW,L"%s",L"Unicode Str");

    //Converts ANSI string to Unicode
    swprintf(szW,L"%S", "ANSI Str");
    感觉printf不能实现对数据编码的通用化。
    //要么print ANSI  
    _tprintf(_T("小s %s   "), str);
    //要么print UNICODE
    _tprintf(_T("大S %S "), str);

    ------------------------------------------------------------------------------
    写一篇,结果没有保存到csdn blog上去,又重写,真把我气得够呛!下次吸取教训千万不要在线写文章了,真不安全!

  • 相关阅读:
    spring
    google-c-style
    process想停就停,真爽
    mytop
    Java 图片设置圆角(设置边框,旁白)
    当setTimeout遇到闭包
    FreeMarker辅助
    ImageIO.wtrie生成jpg图片质量损失方案:BufferedImage生成jpg图片文件流
    从BufferedImage到InputStream,实现绘图后进行下载(生成二维码图片并下载)
    使用Javascript 实现类
  • 原文地址:https://www.cnblogs.com/xiaocai0923/p/2181968.html
Copyright © 2011-2022 走看看