96

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?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
yasith
  • 8,981
  • 7
  • 27
  • 32

7 Answers7

149

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
  • 9,389
  • 4
  • 36
  • 28
  • fmt.Scanf took about a minute to scan 1 million integers. – Rusty Rob 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
60

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,691
  • 1
  • 18
  • 24
6

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
}
Rusty Rob
  • 16,489
  • 8
  • 100
  • 116
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
  • 25,399
  • 9
  • 157
  • 140
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
  • 495
  • 1
  • 4
  • 10
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
  • 5,176
  • 4
  • 32
  • 46
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