【问题标题】:Is a CString always null-terminated?CString 总是以空值结尾吗?
【发布时间】:2011-06-29 21:32:47
【问题描述】:

从 CString 接口来看,显然不应假定 CString 是空终止的。但是,实际上有时字符串末尾似乎有一个空字符。 是否有可能在 Windows 实现中创建一个 not 具有空字符的 CString,以便读取字符串末尾之后的一个字符正在查看不同的堆对象?

【问题讨论】:

  • 我第二个 Tony,你的文字听起来很混乱(特别是考虑到一个 C 字符串,以该名称调用,必须有一个空字节终止)。因此,请描述您想要做什么,以及您在执行此操作时遇到的问题。
  • @Tony - 我有一个奇怪的损坏错误,我有一些代码正在读取字符串末尾的内容。我想知道他们是否有联系。 @DarkDust - 我有一个 CString,而不是 C 字符串。
  • 为什么不停止阅读字符串末尾的内容?

标签: mfc cstring


【解决方案1】:

CString 更像是 Visual Basic 字符串或 BSTR。它可以在 CString 的数据部分中包含嵌入的二进制零。但是,当使用各种运算符在 CString 和标准 C 类型以零结尾的字符串之间进行转换时,嵌入的二进制零被视为字符串字符的结尾。所以CString 很像BSTR 类型的变量。

例如,我将以下源代码行放入 MFC 项目并在 Visual Studio C++ 调试器中运行它。

CString myString (_T("this\000is a String."));  // myString will only contain "this" as a zero terminated string.

CString myJJ;
myJJ.Format (_T("this%cisaxxx"), 0);   // this creates a string with an embedded binary zero in it.
int iLen = myJJ.GetLength();      // this returns the length of the complete string, 11 characters
CString myRight = myJJ.Right(4);  // this returns the right most 4 characters, "axxx"
TCHAR  myTbuff[64];
_tcscpy (myTbuff, myJJ);    // this copies the string up to the embedded binary zero into myTbuff

至于下一个堆对象,我不会依赖它。对象如何在内存中布局以及如何使用内存取决于CString 的实现。如果您创建一个CString,则可能会分配一个大小为 64 个字符的缓冲区,无论您放入多少个字符。 CString 提供了GetLength() 方法来找出CString 中有多少个字符,以便使用。还有一些获取和设置特定字符位置的方法。

CString 旨在让程序员能够像在 Visual Basic 中那样根据字符串类型来思考字符串,而不必处理 C 风格的字符串,这些字符串实际上是具有特殊字符串结束符的字符数组,即二进制零。

Edit01 - 编译器参数和对 CString 的影响

Visual Studio 2013 之前的 Visual Studio 编译器允许 CString 类创建 8 位多字节字符集或 16 位 UNICODE 字符串,具体取决于处理源文件时是否定义了 _MBCS 或 _UNICODE。

我在 Visual Studio 2013 之前说的原因是现在似乎不推荐使用 _MBCS(另请参阅 Side-effect of deprecation of MBCS support for MFC in VS 2013)。

这种灵活性的根源是TCHAR 定义,如果定义了_MBCS,它可能是char,如果定义了_UNICODE,它可能是wchar_t。这反过来又决定了 _T()TEXT() 宏会发生什么,这会将带引号的字符串转换为 char 类型的数组或 wchar_t 类型的数组,方法是前置或不前置 L用于表示wchar_t 文本字符串。这也会影响 LPCTSTR(指向 const TCHAR 字符串的指针)或 LPTSTR(指向非 const TCHAR 字符串的指针)的实际类型。

Windows 95/98/ME 在 Windows API 中没有对 UNICODE 的原生支持,Windows NT/2000/XP 也是如此,因此允许选择 UNICODE 以针对 Windows NT 或 MBCS 以针对 Windows 95 是有帮助的。当时的另一个选择是 Microsoft Layer for Unicode,它为 Windows 95/98/ME 的 Windows API 提供了一个 UNICODE 接口。

【讨论】:

    【解决方案2】:

    转换为LPCTSTR 将提供一个以空字符结尾的字符串,但不能保证该字符串在该转换之前以空字符结尾。它可以很容易地终止函数内部的字符串。

    CString 的源代码由 Microsoft 提供,确保最好的方法是查看那里并确切了解事物是如何实现的。当然,它总是可以在下一个版本中更改 - CString 这些年来已经发生了很多变化。

    【讨论】:

      【解决方案3】:

      是的,CString 总是以空值结尾。

      文档说明您可以将 CString 转换为 LPCTSTR,而 LPCTSTR 是以下之一的 typedef:
      __nullterminated CONST WCHAR *
      __nullterminated CONST CHAR *
      取决于是否定义了 UNICODE。

      【讨论】:

        【解决方案4】:

        在此处查看 MSDN 文档:

        http://msdn.microsoft.com/es-es/library/awkwbzyc(v=vs.80).aspx

        基于此,我猜想那里有一个空终止符,您只需要进行一些转换即可获得它。

        【讨论】:

          猜你喜欢
          • 2021-12-17
          • 2010-10-01
          • 1970-01-01
          • 2011-08-29
          • 2012-02-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-07
          相关资源
          最近更新 更多