Golang中二进制整数的接收与打印无效问题排查

Golang中二进制整数的接收与打印无效问题排查 这是我的第一个Go语言程序。它接收一个整数并打印对应的十进制、八进制、十六进制和二进制值。同时也会打印%v和%#v格式。 除了二进制数字外,其他都能正常工作。

以下是程序:

package main
import "fmt"

func main() {

var numberInput int

fmt.Printf("Enter the number: ")

fmt.Scanf("%v", &numberInput)

fmt.Printf("Dec %d\n", numberInput)

fmt.Printf("Hex %#x\n", numberInput)

fmt.Printf("Oct %#o\n", numberInput)

fmt.Printf("Bin %b\n", numberInput)

fmt.Printf("Value Format %v\n", numberInput)

fmt.Printf("Go Value Format %#v\n", numberInput)

}

以下是输出:

C:\Users\pmu\go\src>first.exe
Enter the number: 100
Dec 100
Hex 0x64
Oct 0144
Bin 1100100
Value Format 100
Go Value Format 100

C:\Users\pmu\go\src>first.exe
Enter the number: 0xFFFF
Dec 65535
Hex 0xffff
Oct 0177777
Bin 1111111111111111
Value Format 65535
Go Value Format 65535

C:\Users\pmu\go\src>first.exe
Enter the number: 07777
Dec 4095
Hex 0xfff
Oct 07777
Bin 111111111111
Value Format 4095
Go Value Format 4095

但当我输入二进制数字时,它无法正常工作。注意我尝试在数字开头加上"b",因为如果不这样做,会发生两种情况: 假设我输入"1010",它会被认为是十进制1010 假设我输入"011011",它会被认为是八进制,因为八进制数字以0开头。

C:\Users\pmu\go\src>first.exe
Enter the number: b1010
Dec 0
Hex 0x0
Oct 0
Bin 0
Value Format 0
Go Value Format 0

C:\Users\pmu\go\src>first.exe
Enter the number: bx1010
Dec 0
Hex 0x0
Oct 0
Bin 0
Value Format 0
Go Value Format 0

C:\Users\pmu\go\src>first.exe
Enter the number: 1010b
Dec 1010
Hex 0x3f2
Oct 01762
Bin 1111110010
Value Format 1010
Go Value Format 1010

C:\Users\pmu\go\src>

我知道这不是让程序理解我想要输入二进制值的正确方式,那么我该怎么做呢? 任何帮助都将不胜感激。


更多关于Golang中二进制整数的接收与打印无效问题排查的实战教程也可以访问 https://www.itying.com/category-94-b0.html

8 回复

无需道歉。很高兴能学到新东西。谢谢!

更多关于Golang中二进制整数的接收与打印无效问题排查的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


另请参阅这里的提案#2
https://blog.golang.org

func main() {
    fmt.Println("hello world")
}

感谢。希望将来某个时候能添加这个功能。也许不会。谁知道呢。

基数为零😄很难表示除零以外的任何数字。抱歉有点累了,来一杯🍺

https://play.golang.org/p/y-KGKfmvEPP

成功了!

fmt.Scanf("%v") 只会解析有效的整数字面值,正如你在语言规范关于整数字面值中看到的,根本没有办法表示二进制整数。

可以使用 fmt.Scanf() 来解析二进制数字,如下所示:

fmt.Scanf("%b", &numberInput)

但这样它只会接受二进制数字,输入中除 01 以外的数字将不会被解析为数字的一部分。

如果你需要处理所有进制,可以先扫描一个单词,然后使用 strconv 包将字符串转换为整数。

https://golang.org/pkg/strconv/#ParseInt

strconv.ParseInt() 接受你想要的数值进制作为参数,因此你可以检查想要用于表示二进制的前缀,然后从基数 2 进行转换。转换十六进制、八进制和十进制数字很简单,只需指定基数为 0 即可。

嗨 Johan,

我觉得你发帖时间太晚了,或者一杯🍺就喝多了😉。另外,我写作时不够仔细。(最近几天我的写作状态没达到100%。)对此很抱歉!

当你给 ParseInt() 一个 “base” 为 0 时,这是一个特殊情况。然后它可以解码十六进制、八进制或十进制数字,具体取决于前缀:0x 表示十六进制,0 表示八进制,没有前缀表示十进制。(换句话说,就像在 C/C++/Go 和其他流行的编程语言中一样。)

strconv.ParseInt("0x30", 0, 64)    // "0x30"    (十六进制) ->  48 (十进制)
strconv.ParseInt("0377",0,64)      // "0377"  (八进制) -> 255 (十进制)
strconv.ParseInt("137",0,64)       // "137" (十进制) -> 137 (十进制)

要解码由 10 组成的字符串,你必须识别该字符串表示的是二进制(基数 2)数字,然后调用

strconv.ParseInt("00100",2,64)     // "100" (二进制) -> 4 (十进制)

在Go语言中,fmt.Scanf函数默认不支持直接解析二进制格式的输入。当您使用%v动词时,它会根据输入字符串的格式自动推断为十进制、八进制(以0开头)或十六进制(以0x或0X开头),但不支持二进制前缀。

要正确接收二进制输入,您需要将输入作为字符串读取,然后使用strconv.ParseInt函数显式指定基数为2进行解析。以下是修改后的代码:

package main

import (
    "fmt"
    "strconv"
)

func main() {
    var input string
    
    fmt.Printf("Enter the number: ")
    fmt.Scanf("%s", &input)
    
    // 移除可能的二进制前缀(如"0b"或"b")
    cleanInput := input
    if len(input) > 1 && (input[:2] == "0b" || input[:2] == "0B") {
        cleanInput = input[2:]
    } else if len(input) > 0 && (input[0] == 'b' || input[0] == 'B') {
        cleanInput = input[1:]
    }
    
    // 解析二进制字符串
    numberInput, err := strconv.ParseInt(cleanInput, 2, 64)
    if err != nil {
        fmt.Printf("Error parsing binary number: %v\n", err)
        return
    }
    
    fmt.Printf("Dec %d\n", numberInput)
    fmt.Printf("Hex %#x\n", numberInput)
    fmt.Printf("Oct %#o\n", numberInput)
    fmt.Printf("Bin %b\n", numberInput)
    fmt.Printf("Value Format %v\n", numberInput)
    fmt.Printf("Go Value Format %#v\n", numberInput)
}

这个修改后的程序可以处理以下二进制输入格式:

  • 1010(纯二进制数字)
  • b1010(b前缀)
  • 0b1010(标准二进制前缀)

示例输出:

Enter the number: 1010
Dec 10
Hex 0xa
Oct 012
Bin 1010
Value Format 10
Go Value Format 10

Enter the number: b1010
Dec 10
Hex 0xa
Oct 012
Bin 1010
Value Format 10
Go Value Format 10

Enter the number: 0b1101
Dec 13
Hex 0xd
Oct 015
Bin 1101
Value Format 13
Go Value Format 13

关键修改点:

  1. 将输入类型从int改为string
  2. 使用strconv.ParseInt函数,第二个参数指定基数2(二进制)
  3. 添加了对常见二进制前缀的处理逻辑
  4. 添加了错误处理,当输入不是有效的二进制数字时会显示错误信息
回到顶部