Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use fmt.Scanf in Go

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

package main

import "fmt"

func main() {
    var num int
    for i := 0; i < 10; i++ {
        fmt.Printf("Debug: i : %d ", i)
        fmt.Scanf("%d", &num)
        fmt.Println(num)
    }
}

What happens when I run this code is this :

Debug: i : 0
Enter next number
1
1
Debug: i : 1
Enter next number
1
Debug: i : 2
Enter next number
2
2
Debug: i : 3
Enter next number
2
Debug: i : 4
Enter next number
3
3
Debug: i : 5
Enter next number
3
Debug: i : 6
Enter next number
4
4
Debug: i : 7
Enter next number
4
Debug: i : 8
Enter next number
5
5
Debug: i : 9
Enter next number
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?

like image 314
gprasant Avatar asked Dec 22 '12 04:12

gprasant


People also ask

What is FMT in Go language?

fmt stands for the Format package. This package allows to format basic strings, values, or anything and print them or collect user input from the console, or write into a file using a writer or even print customized fancy error messages. This package is all about formatting input and output.

What does FMT scan do?

The fmt. Scan() function in Go language scans the input texts which is given in the standard input, reads from there and stores the successive space-separated values into successive arguments.

What is FMT Sprintf?

The fmt. Sprintf function in the GO programming language is a function used to return a formatted string. fmt. Sprintf supports custom format specifiers and uses a format string to generate the final output string.


2 Answers

What OS are you using? Windows?

Try this:

package main

import "fmt"

func main() {
    var num int
    for i := 0; i < 10; i++ {
        fmt.Printf("Debug: i : %d\n", i)
        fmt.Println("Enter next number")
        n, err := fmt.Scanf("%d\n", &num)
        if err != nil {
            fmt.Println(n, err)
        }
        fmt.Println(num)
    }
}

Output:

Debug: i : 0
Enter next number
1
1
Debug: i : 1
Enter next number
2
2
Debug: i : 2
Enter next number
3
3
Debug: i : 3
Enter next number
4
4
Debug: i : 4
Enter next number
5
5
Debug: i : 5
Enter next number
6
6
Debug: i : 6
Enter next number
7
7
Debug: i : 7
Enter next number
8
8
Debug: i : 8
Enter next number
9
9
Debug: i : 9
Enter next number
10
10
like image 110
peterSO Avatar answered Oct 05 '22 12:10

peterSO


The above answer is a good suggestion. the code

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

will output the reason of this problem.

  10 unexpected newline

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

package main

import "fmt"

func main() {
    var num int
    for i := 0; i < 10; i++ {
        fmt.Printf("Debug: i : %d ", i)
        fmt.Scanf("%d\n", &num) // add "\n"
        fmt.Println(num)
    }
}

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:

  go run s.go < input.txt

this will work correctly.

like image 36
pexeer Avatar answered Oct 05 '22 12:10

pexeer