StarTrek18
StarTrek18

Reputation: 323

Replace space with '%20' in place in C

I am trying to remove the spaces of a string in place by creating an array of characters that is bigger than the actual string and doing the replacement in place. However, it doesn't seem that the values are copied correctly.

I assumed that you could do char a[7]="aaaa "; so that you have more memory in order to do the replacement, but I guess I am wrong. The problem is that after running the code and printing a, I still get the same string aaaa

NOTE: Notice that I am trying to start writting from the end of the string, so overwritting is not a concern.

NOTE: The expected output for 'test space' would be 'test%20space'

int countSpace(char *str) {
        int nSpaces = 0;
        while (*(str) != '\0') {
                if (*(str) == ' ') {
                        nSpaces++;
                }
                str++;
        }
        return nSpaces;
}

int main()
{
  char a[7]="aaaa ";
  int alength = strlen(a);
  int newSize = alength + countSpace(a)*2;
  a[newSize] = '\0';
  newSize--;

  for (int i = alength - 1; i >= 0; i--) {
          if (a[i] == ' ') {
                  a[newSize] = '0';
                  a[newSize - 1] = '2';
                  a[newSize - 2] = '%';
                  newSize -= 3;
          } else {
                  a[newSize] = a[i];
                  newSize--;
          }
  }

  printf("%s", a);

}

Upvotes: 0

Views: 2730

Answers (3)

Jan Turoň
Jan Turoň

Reputation: 32912

You can use memmove for this:

You need to allocate memory long enough to support extra 2 chars for space. In the following snippet, data2 is long enough to hold replaced spaces from data.

  // prepare memory long enough to hold %20 spaces
  char data[] = "The quick brown fox jumps over the lazy dog";
  int newSize = strlen(data) + countSpace(data)*2;
  char data2[newSize+1];
  strcpy(data2,data);

Now let's replace in-place on data2:

  // replace the spaces in data2
  for(char*s=strchr(data2,' '); s!=NULL; s=strchr(s+1,' ')) {
    memmove(s+2,s,newSize+data2-s); // shift the rest of the string by 2
    memcpy(s,"%20",3); // replace ' ' for '%20'
  }
  data2[newSize] = 0; // end of string

Now the data2 contains

The%20quick%20brown%20fox%20jumps%20over%20the%20lazy%20dog

Upvotes: 1

user149341
user149341

Reputation:

I don't think there's any satisfying way of doing this operation in place. I see that you're trying to do something clever by starting from the end; unfortunately, this doesn't really help.

Let's consider for a moment a small test case: the string "abc def". No matter whether you start from the beginning or the end, you're going to run into that space when you're halfway through, and you're going to need to replace it with three characters (%20). To make this happen, you have to make the three characters beyond that space all scoot over two characters to make room, and that's annoying and difficult to do. (It's actually more difficult when you start from the end, as then you need to make the beginning of the string move backwards, which would require you to have space available before the beginning of the string. If you're going forwards, you can at least move the end of the string into space you've allocated beyond the end.)

Unless there's some reason that you absolutely need to do this operation in place, I'd strongly recommend that you use two buffers. It'll be far easier that way.

Upvotes: 2

Saurabh Saluja
Saurabh Saluja

Reputation: 290

you are wrong here:

 for (int i = alength - 1; i >= 0; i--) {
          if (a[i] == ' ') {
                  a[newSize] = '0';
                  a[newSize-1] = '2';
                  a[newSize-2] = '%';
                  newSize -= 3;
          } else {
                  a[newSize] = a[i];
                  newSize--;
          }
  }

Upvotes: 0

Related Questions