How to use fmt.Sscan to parse integers into an array?

huangapple go评论79阅读模式
英文:

How to use fmt.Sscan to parse integers into an array?

问题

我正在尝试将一个字符串中的整数列表扫描到一个数组(或者可以选择使用切片)中。

package main

import "fmt"

func main() {
    var nums [5]int
    n, _ := fmt.Sscan("1 2 3 4 5", &nums)  // 这样不起作用
    fmt.Println(nums)
}

为了使这段代码起作用,你需要将什么作为Sscan的第二个参数传递?

我知道可以传递nums[0],nums[1]...等等,但我更希望只传递一个参数。

英文:

I'm trying to scan a list of integers from a string into an array (or alternatively, a slice)

package main

import "fmt"

func main() {
	var nums [5]int
    n, _ := fmt.Sscan("1 2 3 4 5", &nums)  // doesn't work
    fmt.Println(nums)
}

What do I need to pass as second argument to Sscan in order for this to work?

I know I could pass nums[0], nums[1] ... etc., but I'd prefer a single argument.

答案1

得分: 6

我不认为这可以作为一个方便的一行代码来实现。因为Sscan接受...interface{}参数,所以你需要传递一个接口切片,因此需要先将你的数组转换为接口切片:

func main() {
    var nums [5]int

    // 转换为接口切片
    xnums := make([]interface{}, len(nums))
    for n := range nums {
        xnums[n] = &nums[n]
    }

    n, err := fmt.Sscan("1 2 3 4 5", xnums...)
    if err != nil {
        fmt.Printf("field %d: %s\n", n+1, err)
    }

    fmt.Println(nums)
}

显然,你可以在接口切片中混合不同类型的值,这样可以更容易地扫描更复杂的字符串。对于仅包含以空格分隔的整数,你可能更好地使用strings.Splitbufio.Scanner以及strconv.Atoi

英文:

I don't think this is possible as a convenient one-liner. As Sscan takes ...interface{}, you would need to pass slice of interfaces as well, hence converting your array first:

func main() {
	var nums [5]int

	// Convert to interfaces
	xnums := make([]interface{}, len(nums))
	for n := range nums {
		xnums[n] = &nums[n]
	}

	n, err := fmt.Sscan("1 2 3 4 5", xnums...)
	if err != nil {
		fmt.Printf("field %d: %s\n", n+1, err)
	}

	fmt.Println(nums)
}

http://play.golang.org/p/1X28J7JJwl

Obviously you could mix different types in your interface array, so it would make the scanning of more complex string easier. For simply space-limited integers, you might be better using strings.Split or bufio.Scanner along with strconv.Atoi.

答案2

得分: 3

为了使其适用于不仅仅是硬编码的字符串,最好使用bufio.Scannerio.Reader接口来完成这个任务:

package main

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

func scanInts(r io.Reader) ([]int, error) {
	s := bufio.NewScanner(r)
	s.Split(bufio.ScanWords)
	var ints []int
	for s.Scan() {
		i, err := strconv.Atoi(s.Text())
		if err != nil {
			return ints, err
		}
		ints = append(ints, i)
	}
	return ints, s.Err()
}

func main() {
	input := "1 2 3 4 5"
	ints, err := scanInts(strings.NewReader(input))
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(ints)
}

输出结果:

[1 2 3 4 5]

Playground

英文:

To allow this to work on more than just hard-coded strings, it's probably better to use a bufio.Scanner, and an io.Reader interface to do this:

package main

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

func scanInts(r io.Reader) ([]int, error) {
	s := bufio.NewScanner(r)
	s.Split(bufio.ScanWords)
	var ints []int
	for s.Scan() {
		i, err := strconv.Atoi(s.Text())
		if err != nil {
			return ints, err
		}
		ints = append(ints, i)
	}
	return ints, s.Err()
}

func main() {
	input := "1 2 3 4 5"
	ints, err := scanInts(strings.NewReader(input))
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(ints)
}

Produces:

>[1 2 3 4 5]

Playground

答案3

得分: 1

除非你特别想使用Sscann,否则你也可以尝试以下替代方法:

  • 将输入字符串按空格分割
  • 遍历结果数组
  • 将每个字符串转换为整数
  • 将结果值存储到整数切片中

像这样:

package main

import (
	"fmt"
	"strconv"
	"strings"
)

func main() {

	nums := make([]int, 0)
	for _, s := range strings.Split("1 2 3 4 5", " ") {
		i, e := strconv.Atoi(s)
		if e != nil {
			i = 0 // 如果不是数字,默认为0
		}
		nums = append(nums, i)
	}
	fmt.Println(nums)
}

http://play.golang.org/p/rCZl46Ixd4

英文:

Unless you're trying to use Sscann specifically you can also try this as an alternative:

  • split the input string by spaces
  • iterate the resulting array
  • convert each string into an int
  • store the resulting value into an int slice

Like this:

package main

import (
	"fmt"
	"strconv"
	"strings"
)

func main() {

	nums := make([]int, 0)
	for _, s := range strings.Split("1 2 3 4 5", " ") {
		i, e := strconv.Atoi(s)
		if e != nil {
			i = 0 // that was not a number, default to 0
		}
		nums = append(nums, i)
	}
	fmt.Println(nums)
}

http://play.golang.org/p/rCZl46Ixd4

huangapple
  • 本文由 发表于 2015年2月19日 18:58:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/28604563.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定