双重空终止字符串

8

我需要将一个字符串格式化为双重空终止字符串,以便使用SHFileOperation。

有趣的是,我发现以下两种方法中只有一种有效:

  // Example 1
  CString szDir(_T("D:\\Test"));
  szDir = szDir + _T('\0') + _T('\0');

  // Example 2  
  CString szDir(_T("D:\\Test"));
  szDir = szDir + _T("\0\0");

  //Delete folder
  SHFILEOPSTRUCT fileop;
  fileop.hwnd   = NULL;    // no status display
  fileop.wFunc  = FO_DELETE;  // delete operation
  fileop.pFrom  = szDir;  // source file name as double null terminated string
  fileop.pTo    = NULL;    // no destination needed
  fileop.fFlags = FOF_NOCONFIRMATION|FOF_SILENT;  // do not prompt the user
  fileop.fAnyOperationsAborted = FALSE;
  fileop.lpszProgressTitle     = NULL;
  fileop.hNameMappings         = NULL;
  int ret = SHFileOperation(&fileop);

有人对此有想法吗?

还有其他方法来添加双终止字符串吗?


任何一种做法都不应该奏效。如果其中一种方法奏效,那只是偶然。 - Greg Hewgill
@ Greg:第二个例子不应该工作吗?因为CString有以下 friend CString operator+( const CString& string, LPCTSTR lpsz );?(我的意思是+操作,而不是将 CString 传递给 SHFileOperation - Eugen Constantin Dinca
@Eugen:不行,因为CString+运算符将第二个操作数视为普通的以NUL结尾的char *,它没有权利查看超出第一个 NUL终止符的内存。 - Greg Hewgill
@Greg:非常有道理。我把“不起作用”的部分解释为“无法编译”。 - Eugen Constantin Dinca
你可能想阅读这篇文章:http://blogs.msdn.com/b/oldnewthing/archive/2010/02/18/9965469.aspx 和这篇文章 http://blogs.msdn.com/b/oldnewthing/archive/2009/10/08/9904646.aspx - juFo
2个回答

9
CString类本身不会出现包含空字符的字符串问题。问题在于如何把空字符放入字符串中。第一个例子有效是因为它附加了一个单独的字符,而不是一个字符串——它接受字符本身而无需检查其是否为空。第二个例子试图附加一个典型的C字符串,按照定义它以第一个空字符结束——实际上你是在附加一个空字符串。

1
@Mr_and_Mrs_D 不仅是单引号,而是将单引号放在单个字符周围。正如Mooing Duck所观察到的那样,您可以将两个字符放在单引号中,但不会将两个字符附加到字符串中。 - Mark Ransom

6

您不能使用 CString 来实现这个目的。您需要使用自己的 char[] 缓冲区:

char buf[100]; // or large enough
strcpy(buf, "string to use");
memcpy(buf + strlen(buf), "\0\0", 2);

尽管你可以只复制一个额外的NUL字节到现有的NUL终止符后面来实现这个功能,但我更喜欢复制两个,以便源代码更准确地反映程序员的意图。

1
@wengseng,你确实可以使用CString来完成这个目的,且示例1就是如何实现。在使用像这样的固定大小缓冲区之前,我会使用std :: vector <char> - Mark Ransom
std::string 也可以使用,而不必回归到 char[] - edA-qa mort-ora-y

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接