-2

I use a function that I found in this question, adapted to replace all spaces with "%20" (probably could be done far more efficiently!):

## Heading ##std::string Main::SpacesForWeb(std::string text) {
    for (std::string::iterator it = text.begin(); it != text.end(); ++it) {
        if (*it == ' ') {
            *it = '%20';
        }
    }
    return text;
}

However when I try to use it for a string such as Local Live Test Server, the output is this:

enter image description here

My last question dealt with string issues and found out that string is typedefed to point to the internal CryString type in the game SDK I am using (CryEngine2). I am now using std::string in order to counter this.

This issue is also reflected in the database I use after this conversion happens and the data is sent to the database:

enter image description here

Why can't I use %20 (and perhaps other URL encoding symbols) in this way, and how can I get this to work? I attempted to do some research on this in order to fix the issue myself, but however nothing relevant came up.

I have tried using *it = (char)"%20"; in-place of *it = (char)"%20";, but however this actually removes the 0 that is appearing in the string instead of replacing the spaces with %20.

Community
  • 1
  • 1
  • 2
    You need `"%20"` (three characters), not `'%20'` (one character). And since the length of that does not match the length of `" "`, a simple replacement of the type you're doing now just isn't going to work. –  Nov 22 '14 at 19:55
  • 1
    Please fix your question (and the title) to be clear whether you're talking about "%20" or "20%", you keep flipping between them. – Jonathan Wakely Nov 22 '14 at 19:56
  • @JonathanWakely Fixed. I don't do much web programming and this shows! –  Nov 22 '14 at 19:58
  • _"I use a HTML POST method for getting the gameservers' information to the database via a PHP script, and for this reason any spaces in the variables must be replaced with %20."_ Hang on.. what?! – Lightness Races in Orbit Nov 22 '14 at 20:44
  • You've removed chunks of text; you haven't explained _why_ you think you need to do this? Granted, it doesn't vastly matter for the question and I'm mostly asking out of curiosity. I want to make sure that you really need to do this because people often misunderstand HTTP requests and what is required to effect them. – Lightness Races in Orbit Nov 22 '14 at 20:47

2 Answers2

10

Because C++ language knows nothing about any "URL encoding". From the point if view of C++ language your '%20' is a multi-character constant that designates some implementation-defined value of type char (multi-character constants is an obscure feature of C and C++ languages).

If you want to (or have to) use "%20" in your string for passing to some URL-aware recipient you will have to insert "%20" as a substring (three characters) into your string.

Your attempts to convert string literal "%20" to character type will achieve nothing. It is not possible to squeeze three characters into the place of one. You will have to "shift" the tail portion of your string in order to provide space for three characters where one used to reside.

Under the circumstances, it might make more sense to generate the new result in a separate string

std::string new_text;

for (std::string::const_iterator it = text.begin(); it != text.end(); ++it) {
    if (*it == ' ') 
      new_text += "%20";
    else
      new_text += *it;
}

return new_text;

Although with some careful programming it is possible to do it directly in the original string.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
5

I have tried using *it = (char)"%20"; in-place of *it = (char)"%20";, but however this actually removes the 0 that is appearing in the string instead of replacing the spaces with %20.

Please don't apply whacky PHP habits to C++, you can't just say "pretend this string is a single character" and expect anything sensible. "%20" is an array, casting it to char takes the address of the first element (which is a 32-bit or 64-bit pointer value) and then truncates it to the size of a char, probably 8-bits, and that is going to give you garbage.

'%' is a character, and '2' is a character, but '%20' is not a character, so you cannot sensibly assign it to a char.

(Technically '%20' is a multi-character constant with an implementation-defined value, which with my compiler is 0x253230, which is clearly too large to fit into my compiler's 8-bit characters)

2.13.3 [lex.ccon] says:

An ordinary character literal that contains more than one c-char is a multicharacter literal. A multicharacterliteral, or an ordinary character literal containing a single c-char not representable in the execution character set, is conditionally-supported, has type int, and has an implementation-defined value.

There are several ways to replace single characters with strings (AndreyT's answer shows a nice simple approach) but just trying to smash something that isn't a char into the byte of memory holding a single char is never going to work.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521