How do you reverse a string in place in C or C++? How do you reverse a string in place in C or C++? c c

How do you reverse a string in place in C or C++?


#include <algorithm>std::reverse(str.begin(), str.end());

This is the simplest way in C++.


Read Kernighan and Ritchie

#include <string.h>void reverse(char s[]){    int length = strlen(s) ;    int c, i, j;    for (i = 0, j = length - 1; i < j; i++, j--)    {        c = s[i];        s[i] = s[j];        s[j] = c;    }}


The standard algorithm is to use pointers to the start / end, and walk them inward until they meet or cross in the middle. Swap as you go.


Reverse ASCII string, i.e. a 0-terminated array where every character fits in 1 char. (Or other non-multibyte character sets).

void strrev(char *head){  if (!head) return;  char *tail = head;  while(*tail) ++tail;    // find the 0 terminator, like head+strlen  --tail;               // tail points to the last real char                        // head still points to the first  for( ; head < tail; ++head, --tail) {      // walk pointers inwards until they meet or cross in the middle      char h = *head, t = *tail;      *head = t;           // swapping as we go      *tail = h;  }}

// test program that reverses its args#include <stdio.h>int main(int argc, char **argv){  do {    printf("%s ",  argv[argc-1]);    strrev(argv[argc-1]);    printf("%s\n", argv[argc-1]);  } while(--argc);  return 0;}

The same algorithm works for integer arrays with known length, just use tail = start + length - 1 instead of the end-finding loop.

(Editor's note: this answer originally used XOR-swap for this simple version, too. Fixed for the benefit of future readers of this popular question. XOR-swap is highly not recommended; hard to read and making your code compile less efficiently. You can see on the Godbolt compiler explorer how much more complicated the asm loop body is when xor-swap is compiled for x86-64 with gcc -O3.)


Ok, fine, let's fix the UTF-8 chars...

(This is XOR-swap thing. Take care to note that you must avoid swapping with self, because if *p and *q are the same location you'll zero it with a^a==0. XOR-swap depends on having two distinct locations, using them each as temporary storage.)

Editor's note: you can replace SWP with a safe inline function using a tmp variable.

#include <bits/types.h>#include <stdio.h>#define SWP(x,y) (x^=y, y^=x, x^=y)void strrev(char *p){  char *q = p;  while(q && *q) ++q; /* find eos */  for(--q; p < q; ++p, --q) SWP(*p, *q);}void strrev_utf8(char *p){  char *q = p;  strrev(p); /* call base case */  /* Ok, now fix bass-ackwards UTF chars. */  while(q && *q) ++q; /* find eos */  while(p < --q)    switch( (*q & 0xF0) >> 4 ) {    case 0xF: /* U+010000-U+10FFFF: four bytes. */      SWP(*(q-0), *(q-3));      SWP(*(q-1), *(q-2));      q -= 3;      break;    case 0xE: /* U+000800-U+00FFFF: three bytes. */      SWP(*(q-0), *(q-2));      q -= 2;      break;    case 0xC: /* fall-through */    case 0xD: /* U+000080-U+0007FF: two bytes. */      SWP(*(q-0), *(q-1));      q--;      break;    }}int main(int argc, char **argv){  do {    printf("%s ",  argv[argc-1]);    strrev_utf8(argv[argc-1]);    printf("%s\n", argv[argc-1]);  } while(--argc);  return 0;}
  • Why, yes, if the input is borked, this will cheerfully swap outside the place.
  • Useful link when vandalising in the UNICODE: http://www.macchiato.com/unicode/chart/
  • Also, UTF-8 over 0x10000 is untested (as I don't seem to have any font for it, nor the patience to use a hexeditor)

Examples:

$ ./strrev Räksmörgås ░▒▓○◔◑◕●░▒▓○◔◑◕● ●◕◑◔○▓▒░Räksmörgås sågrömskäR./strrev verrts/.