WEB开发网
开发学院软件开发C++ C++字符串完全指引之一:Win32 字符编码 阅读

C++字符串完全指引之一:Win32 字符编码

 2010-10-15 09:08:06 来源:Web开发网   
核心提示:当使用 GetConfigFileName() 检查尾部的''\''时,它寻找安装目录名中最后的非0字节,C++字符串完全指引之一:Win32 字符编码(3),看它是等于''\''的,所以没有重新增加一个''\'',Unic

当使用 GetConfigFileName() 检查尾部的''\''时,它寻找安装目录名中最后的非0字节,看它是等于''\''的,所以没有重新增加一个''\''。结果是代码返回了错误的文件名。

哪里出错了呢?看看上面两个被用蓝色高量显示的字节。斜杠''\''的值是0x5c。'' ''的值是83 5c。上面的代码错误的读取了一个 trail byte,把它当作了一个字符。

正确的后向遍历方法是使用能够识别DBCS字符的函数,使指针移动正确的字节数。下面是正确的代码。(指针移动的地方用红色标明)

bool FixedGetConfigFileName ( char* pszName, size_t nBuffSize )
{
  char szConfigFilename[MAX_PATH];
  // Read install dir from registry... we''ll assume it succeeds.
  // Add on a backslash if it wasn''t present in the registry value.
  // First, get a pointer to the terminating zero.
  char* pLastChar = _mbschr ( szConfigFilename, '''' );
  // Now move it back one double-byte character.
  pLastChar = CharPrev ( szConfigFilename, pLastChar );
  if ( *pLastChar != ''\'' )
    _mbscat ( szConfigFilename, "\" );
  // Add on the name of the config file.
  _mbscat ( szConfigFilename, "config.bin" );
   // If the caller''s buffer is big enough, return the filename.
  if ( _mbslen ( szInstallDir ) >= nBuffSize )
    return false;
  else
    {
    _mbscpy ( pszName, szConfigFilename );
    return true;
    }
}

上面的函数使用CharPrev() API使pLastChar向后移动一个字符,这个字符可能是两个字节长。在这个版本里,if条件正常工作,因为lead byte永远不会等于0x5c。

让我们来想象一个违背规则1的场合。例如,你可能要检测一个用户输入的文件名是否多次出现了'':''。如果,你使用++操作来遍历字符串,而不是使用CharNext(),你可能会发出不正确的错误警告如果恰巧有一个trail byte它的值的等于'':''的值。

与规则2相关的关于字符串索引的规则:

2a. 永远不要使用减法去得到一个字符串的索引。

违背这条规则的代码和违背规则2的代码很相似。例如,

char* pLastChar = &szConfigFilename [strlen(szConfigFilename) - 1];

这和向后移动一个指针是同样的效果。

回到关于str***()和_mbs***()的区别

现在,我们应该很清楚为什么_mbs***()函数是必需的。Str***()函数根本不考虑DBCS字符,而_mbs***()考虑。如果,你调用strrchr("C:\ ", ''\''),返回结果可能是错误的,然而_mbsrchr()将会认出最后的双字节字符,返回一个指向真的''\''的指针。

关于字符串函数的最后一点:str***()和_mbs***()函数认为字符串的长度都是以char来计算的。所以,如果一个字符串包含3个双字节字符,_mbslen()将会返回6。Unicode函数返回的长度是按wchar_t来计算的。例如,wcslen(L"Bob")返回3。

上一页  1 2 3 4 5  下一页

Tags:字符串 完全 指引

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接