在golang中用Unicode而不是UTF-8(十六进制)从控制台读取输入

时间:2016-06-07 11:13:43

标签: go unicode utf-8

我正在尝试在控制台中使用bufio读取用户输入。文本可以有一些特殊字符(é,à,♫,╬,...)。

代码如下所示:

reader := bufio.NewReader(os.Stdin)
input, _ := reader.ReadString('\n')

如果我键入例如“é”,则ReadString将其读作“c3 a9”而不是“00e9”。如何读取Unicode而不是UTF-8的文本输入?我需要将此值用作哈希表键。

由于

2 个答案:

答案 0 :(得分:1)

Go字符串在概念上是只读字节的只读片。未指定该bytearray的编码,但字符串常量将为UTF-8,并且在其他字符串中使用UTF-8是推荐的方法。

Go提供了便利功能,可以将UTF-8作为unicode代码点(或者说话中的符文)进行访问。字符串上的范围循环将为您执行utf8解码。转换为[]符文将按顺序为您提供符文切片,即unicode代码点。这些好东西只适用于UTF-8编码的字符串/字节数组。我强烈建议在内部使用UTF-8。

一个例子:

package main

import (
  "bufio"
  "fmt"
  "os"
)

func main() {
  reader := bufio.NewReader(os.Stdin)
  input, _ := reader.ReadString('\n')


  println("non-range loop - bytes")
  for i := 0; i < len(input); i++ {
    fmt.Printf("%d %d %[2]x\n", i, input[i])
  }
  println("range-loop - runes")
  for idx, r := range input {
    fmt.Printf("%d %d %[2]c\n", idx, r)
  }

  println("converted to rune slice")
  rs := []rune(input)
  fmt.Printf("%#v\n", rs)
}

输入:XéX

    non-range loop - bytes
    0 88 58
    1 32 20
    2 195 c3
    3 169 a9
    4 32 20
    5 88 58
    6 10 a
    range-loop - runes
    0 88 X
    1 32
    2 233 é
    4 32
    5 88 X
    6 10

    converted to rune slice
    []int32{88, 32, 233, 32, 88, 10}

答案 1 :(得分:0)

Unicode和utf8无法比较。字符串可以是unicode和utf8。通过阅读Strings, bytes, runes and characters in Go,我学到了很多关于这些的东西。

要回答你的问题,

您可以使用unicode/utf8包中的DecodeRuneInString

s := "é"
rune, _ := utf8.DecodeRuneInString(s)
fmt.Printf("%x", rune)

DecodeRuneInString(s)的作用是,它返回s中第一个utf8编码字符(符文)以及字节宽度(以字节为单位)。因此,如果您想在字符串中获取每个符文的unicode代码点,那么该怎么做。这是链接文档中给出的示例,只是稍作修改。

str := "Hello, 世界"

for len(str) > 0 {
    r, size := utf8.DecodeRuneInString(str)
    fmt.Printf("%x %v\n", r, size)

    str = str[size:]
}

试试Playground

或者,正如Juergen指出的那样,您可以在字符串上使用范围循环来获取字符串中包含的符文。

str := "Hello, 世界"

for _, rune := range(str) {
    fmt.Printf("%x \n", rune)
}

试试Playground