如何去与Windows控制台输出正确的字符串?(How to properly output a s

2019-06-27 04:49发布

我有一个exe中去哪个打印UTF-8编码字符串,在它的特殊字符。
由于该exe文件是由从一个控制台窗口中使用,其输出是错位的,因为Windows使用ibm850编码(又名code page 850 )。

你将如何确保旅途中exe打印正确编码字符串控制台窗口,即打印,例如:

éèïöîôùòèìë

代替(无需任何转换到右侧的字符集 )

├®├¿├»├Â├«├┤├╣├▓├¿├¼├½

Answer 1:

// 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")
}


Answer 2:

在线图书“ 网络编程与围棋 ”( 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))
}


Answer 3:

自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的线程 。



Answer 4:

这是去还是不能做到开箱即用的东西-看http://code.google.com/p/go/issues/detail?id=3376#c6 。

亚历克斯



文章来源: How to properly output a string in a Windows console with go?