技术

C语言翻转字符串

一、教科书做法:

#include <stdio.h>

void reverse(char * pcStr) {
    if(pcStr == 0) {
        return;
    }
    
    char *pcBegin = pcStr, *pcEnd = pcStr, cTemp;
    while(*(pcEnd) != '\0') {
        pcEnd++;
    }
    pcEnd--;
    
    while(pcEnd > pcBegin) {
        
        cTemp = *pcEnd;
        *pcEnd = *pcBegin;
        *pcBegin = cTemp;
        
        pcBegin++;
        pcEnd--;
    }
}

int main()
{
    //char test_string[300] = {"別れ雨が私の心を濡れるらす"};
    char test_string[300] = {"0123456789"};
    printf("test_string:    %s\n", test_string);
    reverse(test_string);
    printf("reversed_string:%s\n", test_string);
    return 0;
}

上述方法的的缺点是:不支持utf-8等多字节字符串的翻转。

二、XOR-swap方法。

#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()
{
    char test_string[100] = {"別れ雨が私の心を濡れるらす"};
    printf("test_string:    %s\n", test_string);
    strrev_utf8(test_string);
    printf("reversed_string:%s\n", test_string);
    
    char test_string_b[100] = {"abcdefg0123456789"};
    printf("test_string:    %s\n", test_string_b);
    strrev_utf8(test_string_b);
    printf("reversed_string:%s\n", test_string_b);
    
    printf("\n");
    printf("原理如下:\n");
    int c = 0x01;
    c ^= 0x10;
    printf("0x01 ^= 0x10: 0x%x\n", c);
    printf("\n");

    char a[2] = {"a"};
    char b[2] = {"b"};
    
    printf("a: %s, b: %s\n", a, b);
    printf("SWP(*a, *b)\n");
    SWP(*a, *b);
    printf("a: %s, b: %s\n", a, b);
    
    printf("\n");
    
    printf("a: %s, b: %s\n", a, b);
    printf("(x^=y, y^=x, x^=y)\n");
    *a^=*b;
    *b^=*a;
    *a^=*b;
    printf("a: %s, b: %s\n", a, b);
    
    return 0;
}

该方法使用XOR-swap方法来转换单字节字符串,并对多字节字符串进行特殊处理。

引用:

https://stackoverflow.com/questions/198199/how-do-you-reverse-a-string-in-place-in-c-or-c

发表评论

电子邮件地址不会被公开。 必填项已用*标注