我有一个exe
中去哪个打印UTF-8编码字符串,在它的特殊字符。
由于该exe文件是由从一个控制台窗口中使用,其输出是错位的,因为Windows使用ibm850
编码(又名code page 850
)。
你将如何确保旅途中exe
打印正确编码字符串控制台窗口,即打印,例如:
éèïöîôùòèìë
代替(无需任何转换到右侧的字符集 )
├®├¿├»├Â├«├┤├╣├▓├¿├¼├½
我有一个exe
中去哪个打印UTF-8编码字符串,在它的特殊字符。
由于该exe文件是由从一个控制台窗口中使用,其输出是错位的,因为Windows使用ibm850
编码(又名code page 850
)。
你将如何确保旅途中exe
打印正确编码字符串控制台窗口,即打印,例如:
éèïöîôùòèìë
代替(无需任何转换到右侧的字符集 )
├®├¿├»├Â├«├┤├╣├▓├¿├¼├½
// Alert: This is Windows-specific, uses undocumented methods, does not
// handle stdout redirection, does not check for errors, etc.
// Use at your own risk.
// Tested with Go 1.0.2-windows-amd64.
package main
import "unicode/utf16"
import "syscall"
import "unsafe"
var modkernel32 = syscall.NewLazyDLL("kernel32.dll")
var procWriteConsoleW = modkernel32.NewProc("WriteConsoleW")
func consolePrintString(strUtf8 string) {
var strUtf16 []uint16
var charsWritten *uint32
strUtf16 = utf16.Encode([]rune(strUtf8))
if len(strUtf16) < 1 {
return
}
syscall.Syscall6(procWriteConsoleW.Addr(), 5,
uintptr(syscall.Stdout),
uintptr(unsafe.Pointer(&strUtf16[0])),
uintptr(len(strUtf16)),
uintptr(unsafe.Pointer(charsWritten)),
uintptr(0),
0)
}
func main() {
consolePrintString("Hello ☺\n")
consolePrintString("éèïöîôùòèìë\n")
}
在线图书“ 网络编程与围棋 ”( CC BY-NC-SA 3.0 )对集(章管理字符集和编码 ),其中扬Newmarch详细介绍了一个字符集转换为另一种 。 但似乎累赘。
这里是一个解决方案使用的库 (我可能会错过一个更简单的一个), 去-字符集 (由罗杰·佩普 )。
我的翻译utf-8
字符串的ibm850
编码的一个,让我在DOS窗口打印:
éèïöîôùòèìë
翻译功能详述如下:
package main
import (
"bytes"
"code.google.com/p/go-charset/charset"
_ "code.google.com/p/go-charset/data"
"fmt"
"io"
"log"
"strings"
)
func translate(tr charset.Translator, in string) (string, error) {
var buf bytes.Buffer
r := charset.NewTranslatingReader(strings.NewReader(in), tr)
_, err := io.Copy(&buf, r)
if err != nil {
return "", err
}
return string(buf.Bytes()), nil
}
func Utf2dos(in string) string {
dosCharset := "ibm850"
cs := charset.Info(dosCharset)
if cs == nil {
log.Fatal("no info found for %q", dosCharset)
}
fromtr, err := charset.TranslatorTo(dosCharset)
if err != nil {
log.Fatal("error making translator from %q: %v", dosCharset, err)
}
out, err := translate(fromtr, in)
if err != nil {
log.Fatal("error translating from %q: %v", dosCharset, err)
}
return out
}
func main() {
test := "éèïöîôùòèìë"
fmt.Println("utf-8:\n", test)
fmt.Println("ibm850:\n", Utf2dos(test))
}
自2016年,您现在可以(2017)考虑golang.org/x/text
,它配备了一个编码字符表 ,包括ISO-8859系列,以及在Windows 1252字符集。
请参阅“ 快去-转换字符编码在Golang ”
r := charmap.ISO8859_1.NewDecoder().Reader(f)
io.Copy(out, r)
这是一个例子打开一个ISO-8859-1的源文本(的提取物my_isotext.txt
),创建目的地文件( my_utf.txt
),并复制第一到第二。
但解码从ISO-8859-1到UTF-8,我们包装了原始文件阅读器( f
用解码器)。
我只是测试(为了图示的伪代码):
package main
import (
"fmt"
"golang.org/x/text/encoding"
"golang.org/x/text/encoding/charmap"
)
func main() {
t := "string composed of character in cp 850"
d := charmap.CodePage850.NewDecoder()
st, err := d.String(t)
if err != nil {
panic(err)
}
fmt.Println(st)
}
其结果是在Windows CMD可读的字符串。
查看更多在这个2018年11月reddit的线程 。
这是去还是不能做到开箱即用的东西-看http://code.google.com/p/go/issues/detail?id=3376#c6 。
亚历克斯