zoukankan      html  css  js  c++  java
  • ANSI,MBCS,Unicode与使用swprintf的陷阱

     

                        ANSI,MBCS,Unicode与使用swprintf的陷阱

                                                                                                     原创作者:CC

           我们可能平时经常使用swprintf这个API函数,其实这个函数存在很容易让人误解的陷阱,有时在我们的程序使用的时候平时不会出现错误,可是这些API函数的误使用可能会产生一些偶然的错误,这些错误是相当的难找的,所以在平时我们写程序就应该对我们每使用的一个API函数都应该足够的了解其正确的用法,就好像是我们把一个CString直接强转为LPTSTR ,这样就会形成潜在的危险,如果我们了解CString的用法,就可以这样更安全的使用:

    CString str ;

    …..//assume str has contain valid data

    LPTSTR lpszBuff =str.GetBuffer(0);

     

    swprintf这个函数的陷阱也像上面说的一样,使用不当都存在潜在的危险,所谓知其然知其所以然’,在分析这个API可能存在的陷阱之前,先简单的说一下与之相关的几个概念:

    ANSI字符集:single-byte character set (SBCS),就是我们平时说的char ,每个字符是一个字节,’\0’作为字符串的结束符.

    MBCS:(multi-byte character set ):有的字符是占两个字节,有的字符是占一个字节,OS提供了一些API对之进行操作,如果是两个字节,包括一个称为”Lead bytes””trail byte”.也是以一个’\0’作为结束符.

    Unicode:又称为宽字符,每个字符占两个字节,以两个字节的’\0’结束

    以上只是简单的介绍一下,详细的可见: String complete Guide

     

    下面进入正题,先看一下这一段代码,猜一下结果是什么:

           wchar_t         strTemp[64];

           swprintf(strTemp,L"%s","ngangche结果");

     

           第一种情况:

                  BYTE* pData =(BYTE*) strTemp;

    int nLen = _mbslen(pData); //结果是:0x0A

           第二种情况:

                       char* pData =(char*) strTemp;

                  int nLen = strlen(pData); //结果是0x0C

     

    第三种情况:

             int nLen = wcslen(strTemp);//结果是0x06

     

    呵呵,为什么同一段内存,会有这么多不同,你可能在想这段内存到底放的什么,因为这个函数名称是有些让人迷惑的,swprintf ,而不是swprintf而不是sprintf ,可能想到,最后strTemp中应该放的是Unicode字符,而实际放的是什么东西呢,为什么第三种情况结果不是我们想要的10而是6,不用着急,看一下这张图就什么都清楚了:

             这会应该明白了为什么了吧!

             上面的API用法,并不是Unicode ,你可以看到0x12ff00 ~0x12ff07ASCII :ngangche(8个字符),而后面的两个中文字符:0x12ff08~0x12ff0b是两个中文字符,后面是两个’\0’,所以用_mbslen算出的结果是正确的,10个字符.这个也不是MBCS,因为MBCS是一个’\0’结束.

             第二种情况就很容易了:中文占两个字符正好是12个字符

             第三种情况也很容易理解12/2 = 6个字符.

            

             看来这个API函数实现并不像我们想像的那么简单,是不是?你以后用的时候就在注意了,其实上面的应该调用wcslen返回正确的结果,看来并不是那么回事了.

             上面代码改成这样,第三个就能得到正确的结果了:

             swprintf(strTemp,L"%s",L"ngangche结果");

           int nLen = wcslen(strTemp); //nLen10,是我们想要得到的结果.

             再看一下内存,就知道为什么:

            

             我们可以看到从0x0012ff00可以看到每个字符占两个字符,这一下结果正确了,一个API的理解不正确就可能导致不可预料的结果!比如上面的这个例子,我想可能引起的问题很多,因为涉及的字符的长度,很容易出问题的,看来写程序要更加细心的呀!

  • 相关阅读:
    python 函数function
    安装python 第三方库遇到的安装问题 microsoft visual studio c++ 10.0 is required,Could not find function xmlCheckVersion in library libxml2. Is libxml2 installed?
    Pandas库入门
    pyplot基础图表函数概述
    Matplotlib库介绍
    Numpy数据存取与函数
    NumPy库入门
    css3知识
    HTML标签marquee实现滚动效果
    JQuery导航选择特效
  • 原文地址:https://www.cnblogs.com/cc011/p/191578.html
Copyright © 2011-2022 走看看