私はドイツ人ですから、ä
、ö
、ü
のようなウムラウトを使用しています。 Golangはstdinから正しく読まない。 Golang stdinはドイツのウムラウトを間違って読みます
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
for {
b, _, _ := bufio.NewReader(os.Stdin).ReadLine()
printBytes(b)
}
}
func printBytes(bytes []byte) {
for _, b := range bytes {
fmt.Printf("0x%X ", b)
}
fmt.Println()
}
が、私は出力を得る:私はこの単純なプログラム実行
C:\dev\golang>go run test.go
ä
0xE2 0x80 0x9E
E2 80 9E
はUTF-8でä
の正しいバイトシーケンス(this toolではありませんが、それはです私に語りました"DOUBLE LOW-9 QUOTATION MARK" - >„
)、私が読んだことだけを印刷すると、"
が印刷されます。
package main
/*
#include <stdio.h>
#include <stdlib.h>
char * getline(void) {
char * line = malloc(100), * linep = line;
size_t lenmax = 100, len = lenmax;
int c;
if(line == NULL)
return NULL;
for(;;) {
c = fgetc(stdin);
if(c == EOF)
break;
if(--len == 0) {
len = lenmax;
char * linen = realloc(linep, lenmax *= 2);
if(linen == NULL) {
free(linep);
return NULL;
}
line = linen + (line - linep);
linep = linen;
}
if((*line++ = c) == '\n')
break;
}
*line = '\0';
return linep;
}
void freeline(char* ptr) {
free(ptr);
}
*/
import "C"
import (
"fmt"
"golang.org/x/text/encoding/charmap"
)
func getLineFromCp850() string {
line := C.getline()
goline := C.GoString(line)
C.freeline(line)
b := []byte(goline)
ub, _ := charmap.CodePage850.NewDecoder().Bytes(b)
return string(ub)
}
func main() {
for {
line := getLineFromCp850()
printBytes([]byte(line))
}
}
func printBytes(bytes []byte) {
for _, b := range bytes {
fmt.Printf("0x%X ", b)
}
fmt.Println()
}
そして、それは出て印刷します:私は小さな修正文字を読むように思われた「ハック」を書いた
C:\dev\golang>go run test.go
ä
0xC3 0xA4 0xA
C3 A4
はä
の正しいbytesequenceです(0Aがどの改行ですCP850からUTF-8への読み込みと変換は私の予想どおりですが、cgoの代わりにGoの機能を使って行を読んだとき、なぜ私は不安を感じますか? Goで何が問題なのですか?CP850として入力バイトを解釈するのではなく、別の文字セットを解釈しませんか?この問題を処理するためのより良いGo専用の方法はありますか?
をstdinから読み込んだときにのみこの問題が発生します。私がUTF-8 ä
をstdoutに出力すると、コンソールに正しく印刷されます。
あなた自身の質問に答えられませんでしたか? GoはデフォルトでUTF8を仮定していますが、CP850を入力しています – JimB
Goはソースコード内の文字列に対してUTF-8を仮定していますが、端末(cmd.exe)から実行すると、stdinを正しく読み込んで端末のコードページUTF-8?もしGoがUTF-8をコンソールから期待していたとしても、これはなぜ私が完全に無関係なUTF-8文字を得るのかを説明するものではなく、エラー・ルーンだけではありません。私がstdinから直接バイトを読み込んだとしても、私のC関数が 'ä 'のCP850の値を正しく受け取るので、コンソール__definitely__は送信しません。 – tkausl
コンソールが850を使用していても、Golangは入力を850ではなくコードページ1252と解釈するので、[私は問題を作成しました](https://github.com/golang/go/issues/16857) – tkausl