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

新手上路,请多包涵

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

原文由 uvote 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 606
2 个回答

标准算法是使用指向开始/结束的指针,并将它们向内移动,直到它们在中间相遇或交叉。随走随换。


反转 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 字符…

(这是异或交换的事情。请注意,您 必须避免 与 self 交换,因为如果 *p*q 是相同的位置,您将使用 a^a 将其归零==0。异或交换取决于有两个不同的位置,将它们分别用作临时存储。)

编者注:您可以使用 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;
}

  • 为什么,是的,如果输入是 borked,这会很高兴地在这个地方交换。
  • 破坏 UNICODE 时的有用链接:http: //www.macchiato.com/unicode/chart/
  • 此外,UTF-8 over 0x10000 未经测试(因为我似乎没有任何字体,也没有耐心使用 hexeditor)

例子:

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

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

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

./strrev verrts/.

原文由 Anders Eurenius 发布,翻译遵循 CC BY-SA 4.0 许可协议

输入字符串,返回字符串,不需要其他库

std::string reverse_string(std::string &str)
{
  const char*buf = str.c_str();
  char *start = const_cast<char*>(buf);
  char *end = start + strlen(buf) - 1;
  char t;

  while(start < end)
  {
      t = *start;
      *start = *end;
      *end = t;
      start ++;
      end --;
  }
  str = buf;
  return str;
}

 std::string md1 = "abcdefghijklmnopqrstuvwxyz0123456789";
std::cout << reverse_string(md1) << std::endl;

//9876543210zyxwvutsrqponmlkjihgfedcba

原文由 Driver 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题