如何在C或C ++中反转字符串?

紫外线

如何在C或C ++中反转字符串而不需要单独的缓冲区来保存反转的字符串?

安德斯·欧仁纽斯(Anders Eurenius)

标准算法是使用指向起点/终点的指针,并将它们向内移动,直到它们在中间相遇或交叉。随手交换。


反向ASCII字符串,即以0结尾的数组,其中每个字符都适合1 char(或其他非多字节字符集)。

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

相同的算法适用于已知长度的整数数组,只是使用tail = start + length - 1而不是末端查找循环。

(编者注:此答案最初也用于此简单版本的XOR-swap。已修复,以供将来阅读此热门问题的读者使用。强烈建议不要使用XOR-swap;它很难阅读,使您的代码编译效率降低。您可以在Godbolt编译器资源管理器上看到使用gcc -O3为x86-64编译xor-swap时,asm循环体要复杂得多。)


好的,让我们修复UTF-8字符...

(这是XOR交换的东西。请注意,您必须避免与self交换,因为如果*p*q处于同一位置,则将a ^ a == 0对其进行清零。XOR交换取决于有两个不同的位置,将它们各自用作临时存储。)

编者注:可以使用tmp变量用安全的内联函数替换SWP。

#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;
}
  • 为什么,是的,如果输入很闷,这会愉快地交换到该位置之外。
  • 破坏UNICODE时的有用链接:http : //www.macchiato.com/unicode/chart/
  • 另外,超过0x10000的UTF-8未经测试(因为我似乎没有任何字体,也没有耐心使用十六进制编辑器)

例子:

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

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

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

./strrev verrts/.

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章