2011-08-30 26 views
2

この '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-bitで書いています。 はその後、私はすべてのバイトを印刷:

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

答えて

4

ピュア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

3

文字列がutf8としてエンコードされている場合は、かなり簡単です。 の長さは、最初のバイトのみを検査することによって、よく形成された utf8シーケンスを取得することができます。

のみをと置き換えてください。utf8の "サブシーケンス"(長さが1を超えるもの) 2回目のパスでは、文字列全体を逆にします。 Voila。

+0

+1は巧妙だが単純な解決策です。それは最適ではありませんが(2回のパス)、実装が簡単で、正しいことが分かります。 –

+0

@wildplasser、私はちょうどvimを通してUbuntuのgnome-terminalの下でプログラムを書いた、私は私の投稿を再編集し、私が追加した出力には非ASCII文字の代わりに不器用なテキストが含まれていた。 – Alcott

+0

まあ、それはutf8でエンコードされていないかもしれません。あなたの*文字列; - ] – wildplasser