2017-12-26 36 views
0

私は母音の音色を変えることによって、ギリシャ語からギリシャ語への簡単な変換をcで行っています。たとえば、greekの文字列にはῶ(unicode:U + 1FF6)という文字列を入力するので、プログラムはı(unicode:U + 1F7D)に変換します。ギリシア語はcによってサポートされていないので、私はそれを動作させる方法を知らない。何か案は?ギリシャ文字の変換

+0

StackOverflowはプログラミングサービスではありません。コードを表示し、どこに止まっているのかを示します。 –

+1

私はStackOverflowがオンラインデバッガではないと考えました。私は私のためのコードを書くように求めなかった、私はちょうど私が私を助けるためのヒントを依頼した。私はあなたのコードの間違った部分のエラーを検索させる代わりに、私の問題を直接書きました。 –

+2

あなたのアイデア/問題を投稿してください - それ以外は広すぎます。 1つの母音置換が可能な場合、 'if()'はうまく動作します。数十または数百の事例がある場合は、他のアプローチを使用する必要があります。 CはUnicodeをサポートします。 – chux

答えて

2

さて、ここにいくつかの簡単なアドバイスがあります。私はC because Unicode is not wel supported (yet)を使用しません。

より良い言語の選択は、Python、Java、...、優れたUnicodeサポートを持つものです。

私は、標準入力から読み込んで標準出力に書き込むユーティリティを書きます。これにより、コマンドラインやスクリプトから簡単に使用できます。私は何かが足りないかもしれないが、(擬似コードで)このようなものになるだろう

while ((inCharacter = getCharacterFromStandardInput) != EOF 
{ 
    switch (inCharacter) 
    { 
     case 'ῶ': outCharacter = ώ; break 
     ... 
    } 

    writeCharacterToStandardOutput(outCharacter) 
} 

あなたはフォーマットを扱う&選択することも必要があります:UTF-8/16/32

これだけです。がんばろう!

+1

ユニコードコードポイントは、UTF-8とUTF-16で可変長です。 UTF-8の小さなサブセットを除いて、1バイトの 'char'として表現することはできません。また、Cは低レベルの言語であり、Unicodeよりも古いCのバージョンであっても、Unicodeを容易に処理できます。しかし、追加の情報がなければ、別の言語を選ぶというあなたの提案はおそらく最高のものです。 –

2

Windows(Windowsではない)を使用すると仮定すると、これはC99/C11ロケールとワイド文字のサポートを使用すると非常に簡単です。

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

wint_t convert(const wint_t wc) 
{ 
    switch (wc) { 
    case L'ῶ': return L'ώ'; 
    default: return wc; 
    } 
} 

int main(void) 
{ 
    wint_t wc; 

    if (!setlocale(LC_ALL, "")) { 
     fprintf(stderr, "Current locale is unsupported.\n"); 
     return EXIT_FAILURE; 
    } 
    if (fwide(stdin, 1) <= 0) { 
     fprintf(stderr, "Standard input does not support wide characters.\n"); 
     return EXIT_FAILURE; 
    } 
    if (fwide(stdout, 1) <= 0) { 
     fprintf(stderr, "Standard output does not support wide characters.\n"); 
     return EXIT_FAILURE; 
    } 

    while ((wc = fgetwc(stdin)) != WEOF) 
     fputwc(convert(wc), stdout); 

    return EXIT_SUCCESS; 
} 

上記プログラムは、標準入力を読み取りに各を変換して出力する。filter.cを考えます。

ワイド文字列と文字には、Lという接頭辞があります。 L'ῶ'はワイド文字定数です。これらは、実行文字セット(コードがコンパイルされる文字セット)がUnicodeであり、それが開発環境に依存する場合にのみ、Unicodeでしかありません。 (幸いなことに、Windowsの外では、UTF-8は現在かなり標準的なものです - and that is a good thing - 上記のようなコードはちょうどいいです)

POSIXyシステムでは(Linux、Android、Mac OS、BSDなど)、 iconv()の機能を使用して、任意の入力文字セットをUnicodeに変換し、変換を行い、最後に任意の出力文字セットに変換することができます。残念ながら、この質問にはとタグ付けされていないので、この質問の範囲外です。

上記の例では、単純なswitch/caseステートメントを使用しています。置換ペアが多数ある場合、例えば、

typedef struct { 
    wint_t from; 
    wint_t to; 
} widepair; 

static widepair replace[] = { 
    { L'ῶ', L'ώ' }, 
    /* Others? */ 
}; 
#define NUM_REPLACE (sizeof replace/sizeof replace[0]) 

と、実行時に、ソートreplace[]qsort()from要素を比較する関数を使用して)、およびワイド文字を交換するかどうかを迅速に判定するためにバイナリ検索を使用します(そうであれば、ワイドどの文字まで)。これは O(ログ N)の操作です。 Nはペアの数であり、キャッシュは大丈夫です。何千もの置換ペアでもこのような問題はありません。 (もちろん、ユーザー入力やコマンドラインオプションからでも、実行時に置換配列を構築することができます。)

ユニコード文字の場合は、uint32_t map_to[0x110000];を使用して各コードポイントを別のユニコードコードポイントに直接マッピングできますが、ワイド文字がユニコードであるかどうかわからないため、できません。コンパイル時までワイド文字のコード範囲はわかりません。もちろん、テストプログラムが上記のreplace[]配列を生成し、そのコードを10進数で出力するマルチステージコンパイルを行うことができます。次に、ビットマップやハッシュテーブルなどの自動グループ化やクラスタリングを実行して、「高速化」します。

しかし実際には、I/O(データの読み書き)は変換自体よりも実際の時間がかかります。変換がボトルネックであっても、変換率はほとんどの人にとって十分です。 (例として、GNUユーティリティでCコードまたはC++コードをコンパイルする場合、プリプロセッサはまず内部的にソースコードをUTF-8に変換します)。