2017-10-22 14 views
2

Tcl_WriteCharsの出力UTF-8文字を正しく設定するための初期設定はありますか?例えばTcl_WriteCharsでUnicodeをサポートするには?

#include <tcl.h> 

int main() 
{ 
     Tcl_Interp *tcl = Tcl_CreateInterp(); 

     Tcl_Channel channel = Tcl_GetStdChannel(TCL_STDOUT); 

     Tcl_WriteChars(channel, "hello\n", -1); 
     Tcl_WriteChars(channel, "你好\n", -1); 
     Tcl_WriteRaw(channel, "你好\n", -1); 

     Tcl_Close(tcl, channel); 

     Tcl_DeleteInterp(tcl); 

     return 0; 
} 

ソースコードはUTF-8エンコーディングで保存され、次の出力は、UTF-8ロケールのLinuxからです:

hello 
?? 
你好 

答えて

3

あなたはUTF-8(およびホストするエンコーディングを設定する必要がありますあなたが実行しているのは、デフォルトのために他のものを使用しているようです)。チャンネルに書き込む前にこれを行います。

Tcl_SetChannelOption(interp, channel, "-encoding", "utf-8"); 

適切に、あなたはそのリターンコードをチェックする必要があります(以下のような)が、すべてのチャネルは、そのオプションとutf-8エンコードのTclに直接焼成する必要があり、それは失敗しません。

if (Tcl_SetChannelOption(interp, channel, "-encoding", "utf-8") != TCL_OK) { 
    return TCL_ERROR; 
} 

[EDIT]:持つもう少し慎重にコードを再読み込み(およびシステムのデフォルトエンコーディングが最初の場所で実際にUTF-8であることが判明)、実際問題がありますあなたはTcl_FindExecutable()と呼んでいないそのルーチンは、実際に何をするか(スクリプト内でinfo nameofexecutableの作業をする以外は)Tclが内部ライブラリを初期化できるように、誤って名前が付けられています。具体的には、エンコーディング管理サブシステムを初期化します。それは、システムエンコーディングが本当に何であるかを明らかにするポイントです(そうでなければ、最も問題の少ない通常のエンコーディングであるiso8859-1に戻ります)。

あなたのコードは次のようになります。

#include <tcl.h> 

int main(int argc, char *argv[]) /// <<<< CHANGED HERE 
{ 
    Tcl_FindExecutable(argv[0]); /// <<<< CHANGED HERE 

    Tcl_Interp *tcl = Tcl_CreateInterp(); 

    Tcl_Channel channel = Tcl_GetStdChannel(TCL_STDOUT); 

    Tcl_WriteChars(channel, "hello\n", -1); 
    Tcl_WriteChars(channel, "你好\n", -1); 
    Tcl_WriteRaw(channel, "你好\n", -1); 

    Tcl_Close(tcl, channel); 

    Tcl_DeleteInterp(tcl); 

    return 0; 
} 

私はあなたが文の後に宣言を置くことに満足しているコンパイラを使用していると仮定しています。これは広く実装されているC99の機能です(そしてC++にもあります)。

+0

ありがとうございます!できます。私は 'iso8859-1'を返す私のホストの' Tcl_GetChannelOption'でチェックしました。私のホストロケールをUTF-8に設定したので、本当に奇妙です。 –

+0

ああ!私はちょうど問題が何であるかを理解しました! 'Tcl_FindExecutable'を呼び出すことはありません。システムエンコーディングが実際にどのようなものなのかが重要です。 –

+0

また、 'tclsh'は' Tcl_MainEx'で 'Tcl_FindExecutable'も頼りにしている' TclpSetInitialEncodings'を呼び出すので、 'tclsh'にはこの問題がないことに気付きました。ところで、私は 'TclInitEncodingSubsystem'でなぜ' TclpSetInitialEncodings'が呼び出されないのでしょうか?それはより適した場所のようです。その関数は 'TclInitSubsystems'によって呼び出されます。これは' Tcl_FindExecutable'と 'Tcl_CreateInterp'の両方によって呼び出されます。私は別のシステムにTclを埋め込み、 'argv0'はその拡張システムには公開されていないので、' Tcl_FindExecutable'を呼び出すことはできません。 –

関連する問題