Reverse a string

karpar posted @ 2008年10月15日 08:28 in Algorithm with tags utf8 string reverse , 1884 阅读

Evil C:

#include <stdio.h>

void strrev(char *p)
{
 
char *q = p;
 
while(q && *q) ++q;
 
for(--q; p < q; ++p, --q)
   
*p = *p ^ *q,
   
*q = *p ^ *q,
   
*p = *p ^ *q;
}

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;
}

(This is XOR-swap thing. Take care to note that you must avoid swapping with self, because a^a==0.)


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

#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)

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

    ░▒▓○◔◑◕● ●◕◑◔○▓▒░

    Räksmörgås sågrömskäR

    ./strrev verrts/.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter