Nate Jenson
Nate Jenson

Reputation: 2794

Read space separated integers from stdin into int slice

I'm trying to read from stdin two lines of an unknown number of space-separated integers. I would like to store each lines ints into their own int slice.

For example, my input may look like this:

1 2 3
4 5 6

and I want to read this into two []int:

[1,2,3]
[4,5,6]

This is what I have so far. scanner.Scan() is giving me the line, but I'm not sure how to convert that into a []int:

package main
import (
    "fmt"
    "os"
    "bufio"
)

func main() {
    var firstLine []int
    var secondLine []int

    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        t := scanner.Text()
    }
}

Upvotes: 9

Views: 7224

Answers (6)

Shivansh Mehta
Shivansh Mehta

Reputation: 1

A simpler way to Handle taking space separated integers in a slice !!

func StringToIntSlice(inputSequence string) []int {
    var slicedIntegerSequence = []int{}
    var splittedSequence = strings.Split(inputSequence, " ")
    for _, value := range splittedSequence {
        intValue, _ := strconv.Atoi(value)
        slicedIntegerSequence = append(slicedIntegerSequence, intValue)
    }
    return slicedIntegerSequence
}


func main() {

    var inputSequence string
    var convertedSliceOfIntegers = []int{}
    scanner := bufio.NewScanner(os.Stdin)

    fmt.Println("Enter a Sequence of 10 Integers separated by spaces:")
    scanner.Scan()
    inputSequence = scanner.Text()
    convertedSliceOfIntegers = StringToIntSlice(inputSequence)
}

Upvotes: 0

Zombo
Zombo

Reputation: 1

For another option, you can implement fmt.Scanner:

package main

import (
   "bytes"
   "fmt"
)

type slice struct {
   tok []int
}

func (s *slice) Scan(state fmt.ScanState, verb rune) error {
   tok, err := state.Token(false, func(r rune) bool { return r != '\n' })
   if err != nil { return err }
   if _, _, err := state.ReadRune(); err != nil {
      if len(tok) == 0 {
         panic(err)
      }
   }
   b := bytes.NewReader(tok)
   for {
      var d int
      _, err := fmt.Fscan(b, &d)
      if err != nil { break }
      s.tok = append(s.tok, d)
   }
   return nil
}

func main() {
   var s slice
   fmt.Scan(&s)
   fmt.Println(s.tok) // [1 2 3]
}

https://golang.org/pkg/fmt#Scanner

Upvotes: 0

Aswin
Aswin

Reputation: 51

If you are looking for code to read input to solve problems in hackathons, here is your best solution

package main

import (
    "bufio"
    "os"
    "fmt"
)

func main() {

    reader := bufio.NewReader(os.Stdin)

    a:= read(reader,100000)

    fmt.Println(a)
}

func read (reader *bufio.Reader, n int)([]uint32) {

    a := make([]uint32, n)
    for i:=0; i<n; i++ {
        fmt.Fscan(reader, &a[i])
    }

    return a
}

Upvotes: 5

Marcus Pereira
Marcus Pereira

Reputation: 219

package main

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

// You receive a string as parameter
// List receives N As a string slice
// Returns N as a string slice
func number(n string) []string {
    list := strings.Fields(n)

    return list
}

func main() {
    scanner := bufio.NewScanner(os.Stdin) //Receiving user data ...

    list := make([][]string, 0) // Declare a slice to receive other slices inside it

    for scanner.Scan() { // Scrolls all typed data to true

        // If the user does not type anything, that is, if he presses Enter an interrupt will occur
        if scanner.Text() == "" {
            break
        } else {
            list = append(list, number(scanner.Text())) // Adding the slice inside list
        }
    }

    fmt.Println(list) // print list
}

All data is going and returning as string, but you can convert them to integers easily.

Upvotes: -1

peterSO
peterSO

Reputation: 166569

For example,

numbers.go:

package main

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

func numbers(s string) []int {
    var n []int
    for _, f := range strings.Fields(s) {
        i, err := strconv.Atoi(f)
        if err == nil {
            n = append(n, i)
        }
    }
    return n
}

func main() {
    var firstLine, secondLine []int
    scanner := bufio.NewScanner(os.Stdin)
    for i := 1; i <= 2 && scanner.Scan(); i++ {
        switch i {
        case 1:
            firstLine = numbers(scanner.Text())
        case 2:
            secondLine = numbers(scanner.Text())
        }
    }
    fmt.Println(firstLine)
    fmt.Println(secondLine)
}

Output:

$ go run numbers.go
1 2 3
4 5 6
[1 2 3]
[4 5 6]
$

Upvotes: 10

Nate Jenson
Nate Jenson

Reputation: 2794

So, this is what I ended up doing. There is likely a more idiomatic way of solving it, though.

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

func main() {

    scanner := bufio.NewScanner(os.Stdin)

    scanner.Scan()
    parts := strings.Split(scanner.Text(), " ")
    lineOne := createIntSlice(parts)

    scanner.Scan()
    parts = strings.Split(scanner.Text(), " ")
    lineTwo := createIntSlice(parts)

    fmt.Println(lineOne)
    fmt.Println(lineTwo)
}

func createIntSlice(nums []string) []int {
    var r []int
    for _, v := range nums {
        i, _ := strconv.Atoi(v)
        r = append(r, i)
    }
    return r
}

Upvotes: 2

Related Questions