12

特殊文字を含むutf-8でエンコードされた文字列を出力するingoexeがあります。 そのexeはコンソールウィンドウから使用するように作成されているため、Windowsはエンコーディング(別名)を使用するため、その出力は混乱します。
ibm850code page 850

goがコンソールウィンドウ用に正しくエンコードされた文字列を印刷することをどのように確認しますか?exeたとえば、次のように印刷します。

éèïöîôùòèìë

代わりに(正しい文字セットへの変換なしで)

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

4 に答える 4

3
// 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")
}
于 2012-08-21T16:48:23.520 に答える
2

オンラインブック「Goを使用したネットワークプログラミング」(CC BY-NC-SA 3.0 )には、文字セット(文字セットとエンコーディングの管理)に関する章があり、JanNewmarchが1つの文字セットから別の文字セットへの変換について詳しく説明しています。しかし、それは面倒なようです。

これは、ライブラリgo-charsetRoger Peppeから)を使用した解決策です(もっと簡単なものを見逃したかもしれません)。文字列をエンコードされ
た文字列に変換して、DOSウィンドウで印刷できるようにします。utf-8ibm850

éèïöîôùòèìë

翻訳機能の詳細を以下に示します。

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))
}
于 2012-08-21T10:41:42.353 に答える
2

2016年以降、ISO-8859ファミリやWindows1252文字セットを含むエンコーディングcharmapgolang.org/x/textが付属している(2017)を検討できるようになりました。

すばやく実行-Golangでの文字エンコードの変換」を参照してください。

r := charmap.ISO8859_1.NewDecoder().Reader(f)
io.Copy(out, r)

my_isotext.txtこれは、ISO-8859-1ソーステキスト( )を開き、宛先ファイル(my_utf.txt)を作成し、最初のファイルを2番目のファイルにコピーする例の抜粋です。
ただし、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)
}

結果は、WindowsCMDで読み取り可能な文字列です。この2018年11月のredditスレッド
で詳細をご覧ください。

于 2017-07-08T20:29:14.343 に答える
0

これは、Goがそのままでは実行できないことです。http://code.google.com/p/go/issues/detail ?id = 3376#c6を参照してください。

アレックス

于 2012-08-22T00:30:10.327 に答える