有什么简单的方法可以用 CString 中的 space 替换 %20 吗?

Is there any easy way to replace %20 by a space in a CString?

我需要用空格替换一些 %20,但出现了我不理解的编译错误:

CString str = _T("foo%20bar");
str.Replace('%20',' '); // C4305 argument: truncation from 'int' to 'wchar_t'
str.Replace(_T('%20'),_T(' ')); // C4305 argument: truncation from 'int' to 'wchar_t'
str.Replace(_T("%20"),_T(" ")); // C2664 'int ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::Replace(const wchar_t *,const wchar_t *)': cannot convert argument 1 from 'const char [4]' to 'wchar_t'        

怎么了?

CString::Replace() 方法将 null-terminated 字符串指针作为输入,而不是单个字符。您的字符串文字需要使用 " 而不是 ',例如:

CString str = _T("foo%20bar");
str.Replace(_T("%20"), _T(" "));

请注意,与您上一个示例相匹配,您说的也是错误的。唯一可能因显示的错误消息而失败的方法是,如果您的项目配置错误,其中 UNICODE 被定义为 1_UNICODE 不是定义 2.

1:正如 CString 映射到 CStringT<wchar_t> 所证明的那样。

2:编译器说 _T("%20")const char[] 而不是 const wchar_t[]

CString 使用来自 Win32 API 的 TCHAR,而不是来自 C 运行时库的 _TCHAR通常它们是可以互换的,但在您的情况下并非如此。因此,您需要修复项目的配置,以便也定义 _UNICODE,或者使用 Win32 TEXT() 宏来匹配 CStringTCHAR 的使用:

CString str = TEXT("foo%20bar");
str.Replace(TEXT("%20"), TEXT(" "));

或者,完全停止使用基于 TCHAR 的 API(TCHAR 可以追溯到 Win9x/ME 的时代,当时微软正在推动每个人开始迁移他们的code to Unicode),如果可以避免的话,真的不应该在现代编码中使用它。直接使用 wchar_t 字符串即可,例如:

CStringW str = L"foo%20bar";
str.Replace(L"%20", L" ");

最后一个应该有效,除了你似乎在一个没有定义 UNICODE and/or _UNICODE 宏的项目中有一个宽 CString。

在这种组合中,_T() 宏没有为您提供兼容的字符串文字。但是 L"whatever" 会。

str.Replace(L"%20", L" ");

请注意,这可以满足您的要求,但不足以 URL 取消转义。您应该转换所有 %xx 个序列。

%20 可能是像 %d 这样的格式化字符串。并且 Replace 函数 return 替换了 String 而 str 没有被替换。

  • 试一试:str = str.Replace(_T("%%20"), _T(" "));
  • 试试:str = str.Replace(_T("%20"),_T(" "));

额外信息

如果您查看这篇 Format specification syntax: printf and wprintf functions 文章,您将看到以下说明:

A basic conversion specification contains only the percent sign and a type character. For example, %s specifies a string conversion. To print a percent-sign character, use %%. ...