为什么 fmt.Scanf("%s", &name) 打印之前的值

why fmt.Scanf("%s", &name) print the previous value

我做这个代码是为了学习:-

package main

import (
    "fmt"
    "strconv"
)

func main() {

    for {
        name := ""
        fmt.Print("Enter : ")
        fmt.Scanf("%s", &name)
        b1, _ := strconv.ParseBool(name)
        fmt.Printf("%T, %v\n", b1, b1)
    }

}

输出:

Enter : True

bool, true

Enter : bool, false

Enter :

为什么多了一行“Enter: bool, false”? 编辑: 这将在 windows 中的 Powershell、cmd 和 bash 中发生,但不会在 wsl 中发生。

编辑:这是相同的 issue 但这是一个不同的问题。我提到的解决方案已经过时了,在我的回答中提到它后更新了它,但我必须确认并检查它。

我假设您正在使用一些 IDE。

有时他们会弄乱控制台输出,请尝试 运行 直接从本机终端。或者使用 vscode.

我重新输入了你的代码,结果和Sombriks一样,你一定是按错了回车键。

这是一个screenshot

package main

import (
    "fmt"
    "strconv"
)

func main() {
    for {

        name := ""
        fmt.Print("Enter: ")
        fmt.Scanf("%s", &name)
        b, _ := strconv.ParseBool(name)
        fmt.Printf("%T -  %v\n", b, b)
    }
}

编辑:@Daniel Farrell 提到了这个问题 fixed many years ago.,但我在 Windows-terminal 中遇到了这个问题(Powershell、cmd 和 bash)和同样的问题使用 cmder 终端。 wsl 和 MobaXterm 终端不会发生这种情况,我没有进一步检查其他终端。

我不得不提一下,通过在“%s\n”格式字符串中添加新行,有一个旧的“已弃用”解决方法。正如这个 answer

因此下面的代码将适用于所有终端:

package main

import (
    "fmt"
    "strconv"
)

func main() {

    for {
        var name string
        fmt.Print("Enter : ")
        fmt.Scanf("%s\n", &name)
        b1, _ := strconv.ParseBool(name)
        fmt.Printf("%T, %v \n", b1, b1)
    }

}