如何使Tcl_WriteChars支持Unicode?
是否需要进行任何初始设置才能正确输出UTF-8字符?e、 g如何使Tcl_WriteChars支持Unicode?,unicode,utf-8,tcl,Unicode,Utf 8,Tcl,是否需要进行任何初始设置才能正确输出UTF-8字符?e、 g #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(ch
#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(并且您正在运行的主机似乎在使用其他默认值)。在向频道写入之前执行此操作
Tcl_SetChannelOption(interp,channel,“-encoding”,“utf-8”);
正确地说,您应该检查它的返回码(如下所示),但所有通道都有该选项,并且utf-8
编码直接烘焙到Tcl中,因此不会失败
if(Tcl\u设置通道选项(interp,通道,“-encoding”,“utf-8”)!=Tcl\u确定){
返回TCL_错误;
}
[编辑]:重新仔细阅读代码后(首先发现系统的默认编码实际上是UTF-8),实际问题是您没有调用
Tcl\u 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;
}
#包括
int main(int argc,char*argv[])///谢谢!它起作用了。我已经在我的主机中使用Tcl\u GetChannelOption
进行了检查,它返回iso8859-1
。真奇怪,因为我已经将主机区域设置为UTF-8.Oh!我才意识到问题出在哪里!您从未调用Tcl_FindExecutable
;这很重要,因为这就是计算系统编码实际是什么的方法。我还注意到tclsh
没有这个问题,因为它将在Tcl\u MainEx
中调用tclpseetilencodings
(它也依赖于Tcl\u FindExecutable
)。顺便说一句,我很好奇为什么在TclInitEncodingSubsystem
中没有调用TclpSetInitialEncodings
?这似乎是一个更合适的地方。该函数将由tclinitsubsystem
调用,该函数由Tcl\u FindExecutable
和Tcl\u CreateInterp
调用。由于我正在将Tcl嵌入另一个系统,并且argv0
未暴露于其扩展系统,因此无法调用Tcl\u FindExecutable
。您可以传递NULL
而不是argv[0]
。这意味着info nameofexecutable
可能是错误的(取决于平台的内部猜测试探法有多好),但它确实正确初始化了编码和标准通道。(它们是分开的,因为存在一个邪恶的排序依赖项IIRC。)
#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;
}