Viktor Be
Viktor Be

Reputation: 788

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

I need to replace some %20 by spaces and got compile errors which i do not understand:

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'        

What is wrong?

Upvotes: 1

Views: 470

Answers (3)

Samuel D.Murphy
Samuel D.Murphy

Reputation: 191

%20 may be formatted string like %d. and Replace function return replaced String and str is not replaced.

  • try like: str = str.Replace(_T("%%20"), _T(" ")); or
  • try like: str = str.Replace(_T("%20"),_T(" "));

Extra Info

If you look at this Format specification syntax: printf and wprintf functions article you will see the following clarification:

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 %%. ...

Upvotes: 2

Remy Lebeau
Remy Lebeau

Reputation: 597016

The CString::Replace() method takes null-terminated string pointers as input, not individual characters. Your string literals need to use " instead of ', eg:

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

Note that matches your last example, which you say is also erroring. The only way that can fail with the error message you have shown is if you have a misconfiguration in your project, where UNICODE is defined 1 but _UNICODE is not defined 2.

1: as evident by CString being mapped to CStringT<wchar_t>.

2: as evident by the compiler saying _T("%20") is a const char[] rather than a const wchar_t[].

CString uses TCHAR from the Win32 API, not _TCHAR from the C runtime library. Usually they are interchangeable, but not so in your situation. So, you need to either fix your project's configuration so that _UNICODE is also defined, or else use the Win32 TEXT() macro to match CString's use of TCHAR:

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

Or, simply stop using TCHAR-based APIs altogether (TCHAR dates back to the days of Win9x/ME when Microsoft was pushing everyone to start migrating their code to Unicode), and really should not be used in modern coding if you can avoid it. Just use wchar_t strings directly instead, eg:

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

Upvotes: 4

Ben Voigt
Ben Voigt

Reputation: 283733

The last one should have worked, except that you seem to have a wide CString in a project without the UNICODE and/or _UNICODE macro defined.

In this combination, the _T() macro isn't giving you a compatible string literal. But L"whatever" will.

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

Notice that this does what you asked, but is not adequate for URL unescaping. You should convert all %xx sequences.

Upvotes: 3

Related Questions