Home > database >  Read line of numbers in Go
Read line of numbers in Go

Time:08-27

I have the following input, where on the first line is N - count of numbers, and on the second line N numbers, separated by space:

5
2 1 0 3 4

In Python I can read numbers without specifying its count (N):

_ = input()
numbers = list(map(int, input().split()))

How can I do the same in Go? Or I have to know exactly how many numbers are?

CodePudding user response:

You can iterate through a file line-by-line using bufio, and the strings module can split a string into a slice. So that gets us something like:

package main

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

func main() {
    readFile, err := os.Open("data.txt")
    defer readFile.Close()

    if err != nil {
        fmt.Println(err)
    }
    fileScanner := bufio.NewScanner(readFile)

    fileScanner.Split(bufio.ScanLines)

    for fileScanner.Scan() {

        // get next line from the file
        line := fileScanner.Text()

        // split it into a list of space-delimited tokens
        chars := strings.Split(line, " ")

        // create an slice of ints the same length as
        // the chars slice
        ints := make([]int, len(chars))

        for i, s := range chars {
            // convert string to int
            val, err := strconv.Atoi(s)
            if err != nil {
                panic(err)
            }

            // update the corresponding position in the
            // ints slice
            ints[i] = val
        }

        fmt.Printf("%v\n", ints)
    }
}

Which given your sample data will output:

[5]
[2 1 0 3 4]

CodePudding user response:

Since you know the delimiter and you only have 2 lines, this is also a more compact solution:

package main

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

func main() {

    parts, err := readRaw("data.txt")
    if err != nil {
        panic(err)
    }

    n, nums, err := toNumbers(parts)
    if err != nil {
        panic(err)
    }

    fmt.Printf("%d: %v\n", n, nums)
}

// readRaw reads the file in input and returns the numbers inside as a slice of strings
func readRaw(fn string) ([]string, error) {
    b, err := os.ReadFile(fn)
    if err != nil {
        return nil, err
    }
    return regexp.MustCompile(`\s`).Split(strings.TrimSpace(string(b)), -1), nil
}

// toNumbers plays with the input string to return the data as a slice of int
func toNumbers(parts []string) (int, []int, error) {
    n, err := strconv.Atoi(parts[0])
    if err != nil {
        return 0, nil, err
    }
    nums := make([]int, 0)
    for _, p := range parts[1:] {
        num, err := strconv.Atoi(p)
        if err != nil {
            return n, nums, err
        }
        nums = append(nums, num)
    }

    return n, nums, nil
}

The output out be:

5: [2 1 0 3 4]
  • Related