我来自德国,所以我使用变音符号,如ä,ö和ü. 然而,Golang 不能从标准输入正确读取它们。
当我执行这个简单的程序时:
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 中的正确字节序列(这个工具告诉我它是一个“双低 9 引号”-> „),当我打印出我读过的内容时,它会打印出来"。我写了一个小“hack”,似乎可以正确读取字符:
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是正确的字节序列ä(0A 是我的 hack 没有剥离的换行符)所以看起来,从 CP850 读取和转换为 UTF-8 完成了这项工作,正如我所料,但是为什么 Go 会给我胡言乱语当我使用 Go 的功能而不是 cgo 读取该行?Go 有什么问题,它给了我这些值,它不是将输入字节解释为 CP850 而是另一个字符集?有没有更好的 Go-only 方法来处理这个问题?
此问题仅在从标准输入读取时出现。当我将 UTF-8ä打印到标准输出时,它会在控制台中正确打印。
慕姐4208626
相关分类