作者pkmu8426 (巴426)
看板C_Sharp
标题[问题] GBK转编码
时间Tue Jun 17 11:24:08 2014
各位先进好,
目标字(范例): 蹈桶狟婥
我测了一些方式, 想把这串GBK编码的文字转成可识别的中文, 无论是简或繁。
目前已知
1. .Net中任何String的表示形式 都是Unicode
2. System.text.Encodng class提供一些 API可以转
3. 转换时要指定输入编码 输出编码, 并一律以byte[]形式进行转换
相关语法
ex. Encoding.getEncoding("编码").getbytes(string) (转成byte[])
Encoding.convert(原编码,目标编码, 要转的byte[]) (转成byte[])
Encoding.getEncoding("编码").getString(byte[]) (转成string)
等等...
我做了各种测试 但是找不到正确的用法把GBK文字转成中文
顶多show出的结果是原来的GBK目标字而不是乱码。
不晓得原因为何?
如果是.NET不支援GBK, 但我测试过 下面这行
StreamReader(path + ".txt",Encoding.GetEncoding("GBK"));
编码却是转换成功的, 可以正确显示中文。
请问有人知道怎解吗? 谢谢。
--
人生 何必
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 122.118.23.78
※ 文章网址: http://webptt.com/cn.aspx?n=bbs/C_Sharp/M.1402975455.A.3AA.html
1F:→ pkmu8426:不好意思 补充一下 官方语法我有测过, 也都是byte[]时转 06/17 15:37
2F:→ pkmu8426:转出来的结果却是失败@ @ 06/17 15:37
3F:→ pkmu8426:有按照相对应的码去接和解 用法应该是没用错 06/17 15:39
4F:推 Litfal:答:列表下载 06/17 17:07
5F:→ Litfal:你一定想反了。 06/17 17:08
6F:→ Litfal:你想想你最後是因为哪个decode才拿到错的字串?再反推回去 06/17 17:21
7F:→ Litfal:就会得到答案了。 06/17 17:21
抱歉 不是很能理解... 我原不想把语法贴上来 因为可能是错的
但不贴上来 可能大家也不知道错在哪 我下面贴一下。
string s = "蹈桶狟婥";
//转成GBK byte[]
byte[] gbk_byte = Encoding.GetEncoding("gbk").GetBytes(s.ToString());
//转成UTF8 byte[]
byte[] utf8_byte =
Encoding.Convert(Encoding.GetEncoding("gbk"), Encoding.UTF8, gbk_byte);
//转成显示字串
string text = Encoding.UTF8.GetString(utf8_byte);
初步想法是这样 请问哪边是该修正的? 谢谢
8F:→ Litfal:我就说反了吧XD,你是把GBK编码的文件,用其他编码器decode 06/17 21:18
9F:→ Litfal:这时就已经变错的字了。 06/17 21:19
10F:→ Litfal:以你的状况,就是拿BIG5解了GBK的Binary,所以拿到错的字 06/17 21:29
11F:→ Litfal:所以要反过来用BIG5编那串错的字,拿回原始的Binary。 06/17 21:33
12F:→ Litfal:再拿原始的Binary用正确的GBK encoding解成文字。 06/17 21:34
13F:→ Litfal:但要注意,如果在错误的BIG5解时拿到 ? (没有对照的字)那这 06/17 21:35
14F:→ Litfal:样也是转不回来的。 06/17 21:35
谢谢回覆 @ @
我想请问 怎麽知道是Big5?? 我想过可能Win7系统Default可能是UTF8之类
却怎样也没想过朝Big5去想 是Compiler的环境? 或者是我抓的目标本身是Big5..
光从字串就可以看出是Big5编的乱码..
另外所谓的Binary 如果要转的字串来源
如本篇 String s = ""; 直接就是宣告在程式中了 那做法也是一样用Big5去解?
其实我看得懂你的意思 简单说就是我以为的编码 却不只是我以为的。
只是不太懂 明明照API的参数去call 我以为是对 但其实却错了(?) 冒出个Big5
(然後我一直有想到是否该转回Unicode 再继续做进一步的转换。 就是没想到Big5)
如果问题简化一点 纯粹就是宣告在程式中的String 只是内容是GBK,
这样做法会不会不一样??
拍谢问了这麽多 .. 我再努力做看看 谢谢。
※ 编辑: pkmu8426 (122.118.23.78), 06/17/2014 21:54:48
15F:推 watermark001:目前windows系列编码都是GB编码~ 06/17 23:21
16F:→ Litfal:.net的string就是string,虽然他在记忆体中是unicode,但 06/18 00:32
17F:→ Litfal:我不建议把编码的概念和string混淆,把它想的最单纯--就是 06/18 00:32
18F:→ Litfal:个string就对了。 06/18 00:33
19F:→ Litfal:只有二进位和String互相转换时,才该想到编码。 06/18 00:34
20F:推 ideaup:蹈桶狟婥==列表下载 06/18 11:08
21F:推 nfsong:推 06/18 12:41
22F:→ ssccg:string就是string没有编码,所谓编码是把string表示成byte时 06/18 13:54
23F:→ ssccg:的数值,如"列"在GB是C1D0,在Big5是A643,UTF8是E58897 06/18 14:20
24F:→ ssccg:"蹈"在Big5是C1D0,不是"蹈桶狟婥"内容是GBK,而是当初把 06/18 14:41
25F:→ ssccg:"列表下载"用GBK编码成C1D0....,然後再用Big5解码的结果 06/18 14:44
26F:→ ssccg:这单纯是编解码的问题,跟转码没有关系 06/18 14:47
27F:→ ideaup:将(蹈桶狟婥)以ansi 格式储档, 读取为bytes[],再处理 06/18 19:46
哈哈 谢谢各位大德回覆 已经解决。
(原来我前几天曾经看过一篇文後测出的结果 不是错觉 - -)
也的确是跟转码没关系(这边是陷入的第二个迷思!!)
幸好 经过这次经验 我学得更深刻了!
谢谢各位。
我把解法PO在下面
1. 当明确知道最终字串的原始编码(GBK) 以及最後是被哪种编码(Big5) decoding
Encoding Big5 = Encoding.GetEncoding("Big5");
Encoding GBK = Encoding.GetEncoding("GBK");
byte[] big5_byte = Big5.GetBytes("原始字串");
string s_result = GBK.GetString(big5_byte);
2. 当不晓得最终字串是被哪种编码decode 只知道最原始的encoding编码
byte[] big5_byte = Encoding.Default.GetBytes(s);
string s_result = GBK.GetString(big5_byte);
一般来说 用第二种方法比较省事, 看了一篇文章 Default是照所用OS的编码语系
当然 两种方法仅适用经过一层的编、解码 如果中间还经过许多步骤的边解码...
可能必须再靠人工一一测试了。
※ 编辑: pkmu8426 (114.46.222.47), 06/19/2014 00:06:48