反转包含ASCII字符和非ASCII字符的字符串

问题描述:

我收到了有关如何反转包含此'abcd汉字efg'的字符串的问题。反转包含ASCII字符和非ASCII字符的字符串

str_to_reverse = "abcd汉字efg"; /* those non-ASCII chars are Chinese characters, each of them takes 2 bytes */ 

回归后,它应该是:

str_toreverse = "gfe字汉dcba"; 

我认为,扭转串,我得找出那些非ASCII字符,因为我认为,简单地颠倒每个字节不会得到正确的答案。

我该怎么办?

PS: 我在Ubuntu下写了这个程序,32位。 后来我打印的每一个字节:

for(i = 0; i < strlen(s); i++) 
    printf("%c", s[i]); 

我得到了一些乱码文本,而不是“汉字”。

+0

你不应该来识别非ASCII字符,该字符串应该要么有16个字符或8个字符,我不认为你可以混合和匹配。该字符串中的正常ASCII字符实际上是16位字符。 – Kratz

+0

什么平台? VisualC(++)/ gcc/ANSI C? – xanatos

+2

@Kratz这里有一个奇妙的世界......一个充满MBCS和UTF-8的世界:-) – xanatos

纯C89答案:

#include <stdlib.h> 
#include <stdio.h> 
#include <locale.h> 
#include <string.h> 

int main() 
{ 
    char const* str; 
    size_t slen; 
    char* rev; 

    setlocale(LC_ALL, ""); 
    str = "abcd汉字efg"; 
    printf("%s\n", str); 
    slen = strlen(str); 
    rev = malloc(slen+1)+slen; 
    *--rev = '\0'; 
    while (*str != '\0') { 
     int clen, i; 
     clen = mblen(str, slen); 
     if (clen == -1) { 
      fprintf(stderr, "Bad encoding\n"); 
      return EXIT_FAILURE; 
     } 
     for (i = 0; i < clen; ++i) { 
      *--rev = str[clen-1-i]; 
     } 
     str += clen; 
    } 
    printf("%s\n", rev); 
    return 0; 
} 
+1

谢谢你,它的作品。顺便说一下,我应该在程序结束时重新设置区域设置吗? – Alcott

如果字符串被编码为utf8,它非常简单。您只需检查第一个字节即可获得格式正确的 utf8序列的长度。

在第一通你反向的UTF8“子序列”(具有长度> 1) 在第二遍中你扭转整个字符串。 Voila。

+0

+1,这是一个聪明但简单的解决方案。这不是最优的(2遍),但很容易实现,并且看到它是正确的。 –

+0

@wildplasser,我刚刚通过vim在Ubuntu的gnome-terminal下编写了程序,我重新编辑了我的帖子,我添加的输出包含一些乱码文本而不是非ASCII字符。 – Alcott

+0

好吧,也许它不是用utf8编码的。请记住,它是*你的*字符串; - ] – wildplasser