如何在Go中使用fmt.Scanf

huangapple go评论116阅读模式
英文:

How do I use fmt.Scanf in Go

问题

我在使用Go语言的for循环获取用户输入时遇到了一个奇怪的问题。当我运行这段代码时,发生了以下情况:

每次循环迭代都会发生两次,这可能是因为Go默认使用并行处理,导致两个处理器同时运行for循环中的代码吗?

英文:

I seem to be having a queer problem while getting user input within a for loop in go.
Here is my code

  1. package main
  2. import "fmt"
  3. func main() {
  4. var num int
  5. for i := 0; i < 10; i++ {
  6. fmt.Printf("Debug: i : %d ", i)
  7. fmt.Scanf("%d", &num)
  8. fmt.Println(num)
  9. }
  10. }

What happens when I run this code is this :

  1. Debug: i : 0
  2. Enter next number
  3. 1
  4. 1
  5. Debug: i : 1
  6. Enter next number
  7. 1
  8. Debug: i : 2
  9. Enter next number
  10. 2
  11. 2
  12. Debug: i : 3
  13. Enter next number
  14. 2
  15. Debug: i : 4
  16. Enter next number
  17. 3
  18. 3
  19. Debug: i : 5
  20. Enter next number
  21. 3
  22. Debug: i : 6
  23. Enter next number
  24. 4
  25. 4
  26. Debug: i : 7
  27. Enter next number
  28. 4
  29. Debug: i : 8
  30. Enter next number
  31. 5
  32. 5
  33. Debug: i : 9
  34. Enter next number
  35. 5

What I notice is that each iteration of the loop happens twice, Could this be because Go is using parallelism by default and causing both processors to run the code within a for loop?

答案1

得分: 5

尝试这个:

  1. package main
  2. import "fmt"
  3. func main() {
  4. var num int
  5. for i := 0; i < 10; i++ {
  6. fmt.Printf("调试: i : %d\n", i)
  7. fmt.Println("输入下一个数字")
  8. n, err := fmt.Scanf("%d\n", &num)
  9. if err != nil {
  10. fmt.Println(n, err)
  11. }
  12. fmt.Println(num)
  13. }
  14. }

输出:

  1. 调试: i : 0
  2. 输入下一个数字
  3. 1
  4. 1
  5. 调试: i : 1
  6. 输入下一个数字
  7. 2
  8. 2
  9. 调试: i : 2
  10. 输入下一个数字
  11. 3
  12. 3
  13. 调试: i : 3
  14. 输入下一个数字
  15. 4
  16. 4
  17. 调试: i : 4
  18. 输入下一个数字
  19. 5
  20. 5
  21. 调试: i : 5
  22. 输入下一个数字
  23. 6
  24. 6
  25. 调试: i : 6
  26. 输入下一个数字
  27. 7
  28. 7
  29. 调试: i : 7
  30. 输入下一个数字
  31. 8
  32. 8
  33. 调试: i : 8
  34. 输入下一个数字
  35. 9
  36. 9
  37. 调试: i : 9
  38. 输入下一个数字
  39. 10
  40. 10
英文:

What OS are you using? Windows?

Try this:

  1. package main
  2. import &quot;fmt&quot;
  3. func main() {
  4. var num int
  5. for i := 0; i &lt; 10; i++ {
  6. fmt.Printf(&quot;Debug: i : %d\n&quot;, i)
  7. fmt.Println(&quot;Enter next number&quot;)
  8. n, err := fmt.Scanf(&quot;%d\n&quot;, &amp;num)
  9. if err != nil {
  10. fmt.Println(n, err)
  11. }
  12. fmt.Println(num)
  13. }
  14. }

Output:

  1. Debug: i : 0
  2. Enter next number
  3. 1
  4. 1
  5. Debug: i : 1
  6. Enter next number
  7. 2
  8. 2
  9. Debug: i : 2
  10. Enter next number
  11. 3
  12. 3
  13. Debug: i : 3
  14. Enter next number
  15. 4
  16. 4
  17. Debug: i : 4
  18. Enter next number
  19. 5
  20. 5
  21. Debug: i : 5
  22. Enter next number
  23. 6
  24. 6
  25. Debug: i : 6
  26. Enter next number
  27. 7
  28. 7
  29. Debug: i : 7
  30. Enter next number
  31. 8
  32. 8
  33. Debug: i : 8
  34. Enter next number
  35. 9
  36. 9
  37. Debug: i : 9
  38. Enter next number
  39. 10
  40. 10

答案2

得分: 2

上面的答案是一个很好的建议。
代码部分:

  1. if err != nil {
  2. fmt.Println(n, err)
  3. }

将输出这个问题的原因。

  1. 10 unexpected newline

所以我将代码改成这样,然后它就可以工作了。

  1. package main
  2. import "fmt"
  3. func main() {
  4. var num int
  5. for i := 0; i < 10; i++ {
  6. fmt.Printf("Debug: i : %d ", i)
  7. fmt.Scanf("%d\n", &num) // 添加 "\n"
  8. fmt.Println(num)
  9. }
  10. }

这是因为不同的行尾符。Windows 使用回车和换行符(\r\n)作为行尾符。Unix 使用换行符(\n)。

你可以使用 notepad2 创建一个带有 \r 行尾符的文件(a.txt)。
然后执行以下命令:

  1. go run s.go < input.txt

这将正常工作。

英文:

The above answer is a good suggestion.
the code

  1. if err != nil {
  2. fmt.Println(n, err)
  3. }

will output the reason of this problem.

  1. 10 unexpected newline

So I change the code to this, and it works.

  1. package main
  2. import &quot;fmt&quot;
  3. func main() {
  4. var num int
  5. for i := 0; i &lt; 10; i++ {
  6. fmt.Printf(&quot;Debug: i : %d &quot;, i)
  7. fmt.Scanf(&quot;%d\n&quot;, &amp;num) // add &quot;\n&quot;
  8. fmt.Println(num)
  9. }
  10. }

this is because of the different line endings. the windows uses carriage return and line feed(\r\n) as a line ending. the Unix uses the line feed(\n).

you can use notepad2 to create a file (a.txt) with \r line feed.
and do this:

  1. go run s.go &lt; input.txt

this will work correctly.

答案3

得分: 1

只是指出 fmt.Scanln(&num) 可能与 fmt.Scanf("%d\n",&num) 的效果相同,因为 fmt.Scanln(&num) 也会检查 "num" 的类型。

换句话说,如果

  1. var num float32
  2. fmt.Scanln(&num)

你可以从控制台输入浮点数。

英文:

Just to point out fmt.Scanln(&num) would probably work the same as fmt.Scanf("%d\n",&num), since fmt.Scanln(&num) also check the type of "num".

In other words, if

  1. var num float32
  2. fmt.Scanln(&amp;num)

you can input floating number from the console.

答案4

得分: 0

我有同样的问题,我解决了在scanf格式字符串中添加"\n":
fmt.Scanf("%d\n", &num)。

英文:

I have the same problem, i resolved adding "\n" in a scanf format string:
fmt.Scanf("%d\n", &num).

huangapple
  • 本文由 发表于 2012年12月22日 12:33:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/14000082.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定