关于TCL中的编码问题

      在TCL中,默认是使用UTF-8编码的,所有输入的字符串最终都会转换为这一编码。这样就造成了一个问题,通常在不同系统下使用编辑器默认保存的编码是不同的,比如ns中提供的TCL文件都是采用UTF-8进行编码的,而简体中文Windows下默认的保存编码是GB2312(cp936)。

当我们在Windows平台下打开ns中的TCL文档时,首先后将它转换为GB2312,再进行修改,修改完成后如果没有特殊设置就保存为GB2312的文件。如果在此文件中只使用了英文一般不会有什么困扰,因为其在不同编码中保持不变。(!!!打倒英语特权!!!)如果直接在这些文件中使用中文或者其它的语言,就可能造成显示的乱码甚至于程序无法执行。
1、文件中的编码
对于文件中的编码,解决的方法有几种:
一种是修改完成后仍然将TCL文件保存为UTF8编码。不过这种方法转换的汉字有些字无法显示。
另一种是使用TCL中的encoding命令。当使用时出现乱码时,可以这样:
set string [encoding convertfrom cp936 “测试字符串”]
其中cp936必须和文件保存的编码一致,如果使用UTF-8编码,则相应改为utf-8。然后将出现字符串的地方用$string替换即可。
不过这种方法在vs2005下处理UTF-8文件时好像不能通过,原因不明。如果是保存为cp936就可以显示汉字。
这两种方法在实际使用过程中都有一些汉字无法显示,好像是在读取文件时调用了gets这个命令,而这个命令进行了错误的编码转换。当然,这两种方法是最简单的,如果你的汉字刚好可以显示,那么,恭喜了,一切都解决了。
如果这两种方法都不行,那么我们用最后一着:
set title [encoding convertfrom cp936 "/uCE/uC4/uBC/uFE"]
$m add command -label $title -command "puts {File}"
set title [encoding convertfrom cp936 "/uB0/uEF/uD6/uFA"]
$m add command -label $title -command "puts {Help}"
其中CE C4 BC FE就是"文件"两个字的CP936编码
B0 EF D6 FA是"帮助"两个字的CP936编码
这个编码通过UEDIT这样的十六进制编辑器就可以看到了(在文本模式下输入汉字,然后以16进制查看)。
或者自己写一小段C代码进行转换,就更容易了。
2、TCL与C混合编程时的编码问题
参看下面代码进行转换
int _tmain(int argc, _TCHAR* argv[])
{
     // 使用本语句即可使用所有编码
     Tcl_FindExecutable(argv[0]);
     Tcl_Interp *interp = Tcl_CreateInterp();
 
     // 在C中设置TCL变量的值
     string text = " 今天的天气传说是不错的好像" ;
     Tcl_SetVar(interp, "text", text.c_str(), TCL_GLOBAL_ONLY);
     Tcl_SetVar(interp, "ret", "", TCL_GLOBAL_ONLY);
 
     // 对此字符串进行编码转换并进行其它处理
     // 其中cp936就是C文件的编码
     // 运算后的结果存放在$ret变量中
     string code = "set text [encoding convertfrom cp936 $text] /n set ret [string range $text 1 5]";
     Tcl_Eval(interp, code.c_str());
 
     // 在C中取$ret变量的值
     char *ret = 0;
     ret = (char *)Tcl_GetVar(interp, "ret", TCL_GLOBAL_ONLY);
 
     // 在TCL运算的中间都是使用UTF8编码的,最后的结果也是以与编码保存。
     // 如果要在C代码中进行操作,则必须转换为Unicode或者ASCII。
     // 此两行语句的次序不可颠倒,即必须首先转换为Unicode再转换为ASCII(根据需要)。
     // 转换中使用的编码CP_UTF8与CP_ACP不可更改
     wchar_t wchar[1024];
     char ascii[1024];
     int n = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, ret, strlen(ret), wchar, 1024);
     n = ::WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, wchar, n, ascii, 1024, NULL, NULL);
     ascii[n] = 0;
     cout << "eval result: " << ascii << "(" << n << " byets)" << endl;
    
     system("pause");
     Tcl_DeleteInterp(interp);
}
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌云阁主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值