英文:
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.Split
或bufio.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.Scanner
和io.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]
英文:
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]
答案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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论