关于fmt.Scan()和fmt.Scanf()的区别

lovegolang · 2013-04-05 05:08:05 · 17256 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2013-04-05 05:08:05 的主题,其中的信息可能已经有所发展或是发生改变。

有人问道:

我刚开始接触go语言,在根据书写二分法的时候发现个问题。

虽然解决了,但搞不清楚原因是为什么。 代码如下:

package main

import "fmt"

func main() {
    min, max := 0, 100
    fmt.Printf("%d--%d", min, max)
    for min < max  {
        i := (min + max) / 2
        fmt.Printf("<=%d(y or n)  ", i)
        var s string
        fmt.Scanf("%s", &s)
        if s != "" && s[0] == 'y' {
            max = i
        } else {
            min = i + 1
        }
    }
    fmt.Printf("%d\n", max)
}

运行结果: 0--100 <=50(y or n) 输入 n <=75(y or n) <=88(y or n)

这里会连续两次执行 fmt.Printf("<=%d(y or n) ", i) 即

fmt.Scanf("%s", &s)未被执行,或者说默认输入了某项内容,经过试验是默认了""空字符串。 我将fmt.Scanf("%s", &s)改成fmt.Scan(&s)后,这个错误没有再发生。

我对fmt.Scan()和fmt.Scanf()的用法就有了疑问,哪位能详细解释下!!!!! 感谢!!!!!!!!


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

17256 次点击  
加入收藏 微博
8 回复  |  直到 2015-12-14 11:27:06
polaris
polaris · #1 · 12年之前

将Scanf改为:

n, err := fmt.Scanf("%s\n", &s)
if err != nil {
    fmt.Println("error", err)
}

或者,你应该捕获一下fmt.Scanf返回的错误,看看是啥原因,就可以找到对应的解决方案了。

gs272
gs272 · #2 · 12年之前

你这个方法没有用啊?

polaris
polaris · #3 · 12年之前
gs272gs272 #2 回复

你这个方法没有用啊?

我测试过的,怎么可能没用。注意是有"\n"的。

gs272
gs272 · #4 · 12年之前

不好意思,是我没处理n这个变量导致无法编译,我将n替换成_就没问题了。 我还想问下\n在这里起得是什么作用?nil代表什么意思?

polaris
polaris · #5 · 12年之前
gs272gs272 #4 回复

不好意思,是我没处理n这个变量导致无法编译,我将n替换成_就没问题了。 我还想问下\n在这里起得是什么作用?nil代表什么意思?

在写《Golang标准库》fmt一节时,个人感觉这是Go在Windows下的bug,已经向官方提出 https://code.google.com/p/go/issues/detail?id=5391。

nil是go中的关键字,相当于其他语言的null啊;其实加上\n,相当于使用fmt.Scanln()。

gs272
gs272 · #6 · 12年之前

感谢站长,我马上去仔细看看!

CodyGuo
CodyGuo · #7 · 9年之前

fmt.Scanf不能出现2次以上,第二次就会出现跳过无需输入。 应该是个bug

CodyGuo
CodyGuo · #8 · 9年之前

已找到解决方法 // 初始化stdin os.Stdin = os.NewFile(uintptr(syscall.Stdin), "/dev/stdin")

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传