93

How do I use the fmt.Scanf function in Go to get an integer input from the standard input?

If this can't be done using fmt.Scanf, what's the best way to read a single integer?

Flimzy
  • 68,325
  • 15
  • 126
  • 165
yasith
  • 8,289
  • 6
  • 26
  • 32

7 Answers7

142

http://golang.org/pkg/fmt/#Scanf

All the included libraries in Go are well documented.

That being said, I believe

func main() {
    var i int
    _, err := fmt.Scanf("%d", &i)
}

does the trick

cthom06
  • 8,999
  • 3
  • 34
  • 28
  • fmt.Scanf took about a minute to scan 1 million integers. – robert king Jun 06 '13 at 23:36
  • @robertking try using a bufio instead It's a simple example. – cthom06 Jun 07 '13 at 00:05
  • 8
    Can you explain why we must enter `&i` and not just `i` as in `fmt.Printf("%v", i)`? – Zeynel Jul 04 '13 at 22:46
  • 9
    @Zeynel Because parameters are passed by value in Go. `i` is just the integer value in `i`, `&i` is a pointer to `i`. – cthom06 Jul 05 '13 at 12:28
  • @cthom06 what were you using for scanning with bufio? err... I mean if you were using Scanner which interface were you inputting into the Scanner to scan stdin? NVM, looks like golang has an example `scanner := bufio.NewScanner(os.Stdin)` – Greg Sep 15 '13 at 21:14
  • 1
    you need to add `if err != nil { log.Fatal(err) }` otherwise it would throw an error as you have declared `err` and not used it – 0xsegfault Aug 13 '18 at 21:22
56

An alternative that can be a bit more concise is to just use fmt.Scan:

package main

import "fmt"

func main() {
    var i int
    fmt.Scan(&i)
    fmt.Println("read number", i, "from stdin")
}

This uses reflection on the type of the argument to discover how the input should be parsed.

http://golang.org/pkg/fmt/#Scan

iainmcgin
  • 2,561
  • 1
  • 17
  • 24
5

Golang fmt.Scan is simpler than Golang fmt.Scanf (which is simpler than Clang scanf)

If fmt.Scan errors i.e. if not nil, log & return

1 Read single variable:

import (
    "fmt"
    "log"
)

var i int
if    _, err := fmt.Scan(&i);    err != nil {
    log.Print("  Scan for i failed, due to ", err)
    return
}

fmt.Println(i)

2 Read multiple variables:

import (
    "fmt"
    "log"
)

var i, j, k int  
if    _, err := fmt.Scan(&i, &j, &k);    err != nil {
    log.Print("  Scan for i, j & k failed, due to ", err)
    return
}

fmt.Println(i, j, k)

Best of luck

Example from: http://www.sortedinf.com/?q=golang-in-1-hour

Manohar Reddy Poreddy
  • 21,015
  • 9
  • 137
  • 125
4

Here is my "Fast IO" method for reading positive integers. It could be improved with bitshifts and laying out memory in advance.

package main

import (
    "io/ioutil"
    "bufio"
    "os"
    "strconv"
)


func main() {
    out := bufio.NewWriter(os.Stdout)
    ints := getInts()
    var T int64
    T, ints = ints[0], ints[1:]
    ..
    out.WriteString(strconv.Itoa(my_num) + "\n")
    out.Flush()
    }
}

func getInts() []int64 {
    //assumes POSITIVE INTEGERS. Check v for '-' if you have negative.
    var buf []byte
    buf, _ = ioutil.ReadAll(os.Stdin)
    var ints []int64
    num := int64(0)
    found := false
    for _, v := range buf {
        if '0' <= v && v <= '9' {
            num = 10*num + int64(v - '0') //could use bitshifting here.
            found = true
        } else if found {
            ints = append(ints, num)
            found = false
            num = 0
        }
    }
    if found {
        ints = append(ints, num)
        found = false
        num = 0
    }
    return ints
}
robert king
  • 15,381
  • 8
  • 94
  • 111
0

You can use fmt.Scanf with a format specifier. The format specifier for the integer is %d. So you can use standard input like below.

func main() {
    var someVar int
    fmt.Scanf("%d", &someVar)
}

or else you can use fmt.Scan or fmt.Scanln as below.

func main() {
   var someVar int
   fmt.Scanln(&someVar)
}
Kaveen Hyacinth
  • 415
  • 1
  • 4
  • 9
0

You could also use bufio.NewReader to read an integer from the standard input.

The below program:

  • Prompts for an integer input

  • Creates a bufio.Reader to read from standard input

  • Reads input till it encounters a newline character '\n' (Note that this will only read a single integer. Space separated values will not work)

  • Removes the newline character

  • Converts string to int

package main

import (
    "fmt"
    "bufio"
    "os"
    "strconv"
    "strings"
)

func getInt() error {
    fmt.Println("Enter an integer")
    userInput  := bufio.NewReader(os.Stdin)
    userVal, err := userInput.ReadString('\n')
    if err != nil {
        return err
    }

    input := strings.TrimSpace(userVal)
    intVal, err := strconv.Atoi(input)
    if err != nil {
        return err
    }

    fmt.Printf("You entered: %d\n", intVal)
    return nil
}

func main() {
    getInt()
}
Saurabh
  • 2,423
  • 2
  • 22
  • 29
0

Why can't we just use a scanf? just like we use in C? it's working though.

package main
import "fmt"
func main() {
    var i int
    fmt.Scanf("%d", &i)
    fmt.Println(i)
}
sub0d33p
  • 1
  • 3