Как определить текущую кодировку терминала и преобразовать пользовательский ввод в и из utf8?

#windows #go #utf-8 #character-encoding #cross-platform

#Windows #Вперед #utf-8 #кодировка символов #кросс-платформенный

Вопрос:

Я пишу программу командной строки golang, которая принимает пользовательский ввод. Эта строка ввода должна быть преобразована в UTF-8 и отправлена на другой сервер для обработки. В Linux кодировка терминала почти всегда UTF-8, но, похоже, это не так в Windows. Я попытался установить кодовую страницу в Windows на 65001, используя

 chcp 65001
  

а также убедиться, что шрифт терминала установлен на Lucida console. Однако байты, считываемые

 fmt.Scanf()
  

не в формате UTF-8. Я хочу иметь возможность определять кодировку символов и преобразовывать строки в UTF-8. Аналогично, я должен иметь возможность конвертировать из UTF-8 в локальную кодировку перед выводом на экран.

Похоже, что у Python есть пакет «locale», который может получать кодировку по умолчанию, декодировать и кодировать строки в любую указанную кодировку. Есть ли эквивалент этого для golang?

Большинство обсуждений stackoverflow указывало на использование chcp 65001 для изменения кодировки на терминале Windows на UTF-8. Похоже, это не работает для меня.

 func main() {
    foo := ""
    fmt.Printf("Enter: ")
    if _, err := fmt.Scanln(amp;foo) ; err != nil {
        fmt.Println("Error while scanning: ", err)
    }
    fmt.Printf("Scanned bytes: % x", foo)
    fmt.Println()
}
  

В Linux:

 // ASCII
$ go run test.go
Enter: hello
Scanned bytes: 68 65 6c 6c 6f

// Unicode
$ go run test.go
Enter: ©
Scanned bytes: c2 a9

// Unicode
$ go run test.go
Enter: ΆΏΑΓΔΘΞ
Scanned bytes: ce 86 ce 8f ce 91 ce 93 ce 94 ce 98 ce 9e ce a3 ce a8 ce a9 ce aa ce ad ce b1 ce b2 ce ba
  

В Windows:

 PS C:> chcp
Active code page: 437

PS C:> go run .test.go
Enter: hello
Scanned bytes: 68 65 6c 6c 6f

PS C:> go run .test.go
Enter: ΆΏΑΓΔΘΞ
Scanned bytes: 3f 3f 61

// Change to Unicode
PS C:> chcp 65001
Active code page: 65001
PS C:> go run .test.go
Enter: ΆΏΑΓΔΘΞ
Error while scanning:  EOF
Scanned bytes:
  

Ценю любую помощь / указатели.

Комментарии:

1. Я не думаю, что для среды терминала существует стандартный способ отображения кодировки (поскольку вы включили Windows). Лучшее решение, которое я могу придумать, — вручную добавить переменную среды для этого, затем вы читаете переменную с os.Getenv() помощью .

2. Спасибо, @KoalaYeung. Знаете ли вы, как вообще обрабатывается unicode в golang в среде Windows? Scanf / bufio.read, похоже, не считывает ввод, отличный от UTF-8.

3. Извините. У меня нет опыта работы в Windows с Golang. Я прочитал, что в какой-то статье говорится, что вы можете chcp 65001 изменить кодовую страницу на UTF-8. Как вы думаете, это помогает?

4. По-видимому, это не так. Я упоминал об этом в вопросе.

5. @KoalaYeung Да, я пробовал iconv, но опять же, мне нужно сначала определить кодировку терминала. На данный момент я планирую использовать nl_langinfo(CODESET) с некоторым кодом C в программе go.

Ответ №1:

Я запускаю этот код в окне и проверяю его в терминале с помощью git bash, poweshell и т. Д., И Он работает правильно.

возможно, ваша проблема связана с настройкой системного языка.

для получения дополнительной информации о utf8 я рекомендую вам прочитать этот документ пакета