gpt4 book ai didi

Golang stdin 读错了德语变音符号

转载 作者:数据小太阳 更新时间:2023-10-29 03:05:50 27 4
gpt4 key购买 nike

我来自德国,所以我使用变音符号,例如 äöü。然而,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 中 ä 的正确字节序列(this tool 告诉我这是一个“DOUBLE LOW-9 QUOTATION MARK” -> ),当我打印出我读过的内容时,它打印出 "。我写了一个小的“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 的功能而不是 cgo 阅读该行时,Go 会给我乱码? Go 有什么问题,它给了我这些值,它不会将输入字节解释为 CP850 而是另一个字符集吗?有没有更好的 Go-only 方法来处理这个问题?

此问题仅在从标准输入读取 时出现。当我将 UTF-8 ä 打印到标准输出时,它会在控制台中正确打印。

最佳答案

所以对于某些系统来说,这是 Golang 中的一个错误,特别是对于 Windows 系统,在这些系统中,总体使用的字符集和控制台字符集是不同的(其中 GetACP()GetConsoleCP() 来自 WinAPI 返回不同的东西)。例如,在德国(可能还有其他西欧国家),Windows 使用代码页 1252 作为整体字符集,但它使用代码页 850 作为控制台 cmd.exe。不知道为什么,但事实就是如此。 Golang 错误地使用 GetACP() 将输入解码为 UTF-8,而实际上它本应使用 GetConsoleCP() 返回的代码页。我们在 Issue 中发现了问题我创建了,我们希望看到为下一版本的 Golang 合并的修复程序。

我们还在 Windows 上发现了一个问题,其中 Golang 将字符解码为分解的 UTF-8 字符(即它会将 ä 读取为字符 a 后跟 COMBINING DIAERESIS ̈),这可能会导致其他问题,例如,打印那些分解的字符会将它们分开打印,而不是打印一个组合字符。

关于Golang stdin 读错了德语变音符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39111624/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com