Golang输出结果求解释

Golang输出结果求解释

package main

import (
        "fmt"
        "os"
)

func main() {

        var a,b,e,f int

        fmt.Scanf("%d Scanf %d", &a, &b)
        fmt.Scanf("%d Scanf %d", &e, &f)
        fmt.Fprintf(os.Stdout, "%d - %d\n", a, b)
        fmt.Fprintf(os.Stdout, "%d - %d\n", e, f)
}

我运行上述代码的方式是:

echo 1 2 3 4 5 6 | go run program.go

得到的输出结果是:

1 - 0 3 - 0

我想逐步理解 fmt.Scanf() 函数为什么会产生这样的输出结果…


更多关于Golang输出结果求解释的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

Scanf 根据您提供的格式字符串解析后续参数。因此第一次调用期望读取 num Scanf other_num 来将 num 赋值给 a,将 other_num 赋值给 b。如果您按以下方式调用就会看到:

echo 1 Scanf 2\n3 Scanf 4 | ./scanf-test
echo 1 Scanf 2 3 Scanf 4 | ./scanf-test

您将得到预期的输出:

1 - 2
3 - 4

在您的情况下,使用 1 2 3 4 5 6 调用时,程序会扫描 1,丢弃不符合格式的 2,然后在下次调用时继续扫描 3,此时丢弃 4,最终输出所有结果。

您可以在此处阅读更多信息:https://golang.org/pkg/fmt/

更多关于Golang输出结果求解释的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这个输出结果是由于 fmt.Scanf() 的格式化字符串解析方式导致的。让我逐步分析:

问题分析

当输入流为 1 2 3 4 5 6 时:

第一次 fmt.Scanf("%d Scanf %d", &a, &b)

  • %d 匹配数字 1a = 1
  • 然后期望字面字符串 " Scanf "(注意开头的空格)
  • 但输入流中的下一个是 2,不是 "Scanf",所以扫描失败
  • b 保持初始值 0

第二次 fmt.Scanf("%d Scanf %d", &e, &f)

  • 从上次失败的位置继续
  • %d 匹配数字 3e = 3
  • 期望 " Scanf " 但遇到 4,再次失败
  • f 保持初始值 0

代码验证

package main

import (
    "fmt"
    "os"
)

func main() {
    var a, b, e, f int
    
    n1, err1 := fmt.Scanf("%d Scanf %d", &a, &b)
    fmt.Fprintf(os.Stderr, "第一次Scanf: 成功读取 %d 个参数, 错误: %v\n", n1, err1)
    
    n2, err2 := fmt.Scanf("%d Scanf %d", &e, &f) 
    fmt.Fprintf(os.Stderr, "第二次Scanf: 成功读取 %d 个参数, 错误: %v\n", n2, err2)
    
    fmt.Fprintf(os.Stdout, "%d - %d\n", a, b)
    fmt.Fprintf(os.Stdout, "%d - %d\n", e, f)
}

运行输出:

第一次Scanf: 成功读取 1 个参数, 错误: bad verb %!d(string= Scanf )
第二次Scanf: 成功读取 1 个参数, 错误: bad verb %!d(string= Scanf )
1 - 0
3 - 0

正确用法

如果要用 Scanf 读取连续数字,应该使用:

fmt.Scanf("%d%d", &a, &b)  // 读取 1 和 2
fmt.Scanf("%d%d", &e, &f)  // 读取 3 和 4

或者使用 fmt.Scan

fmt.Scan(&a, &b)  // 自动按空格分隔
fmt.Scan(&e, &f)
回到顶部