寻找相当于scanf的Go

Ste*_*Hsu 6 go

我正在寻找与scanf()等效的Go.我尝试使用以下代码:

  1 package main
  2 
  3 import (
  4     "scanner"
  5     "os"
  6     "fmt"
  7 )
  8 
  9 func main() {
 10     var s scanner.Scanner
 11     s.Init(os.Stdin)
 12     s.Mode = scanner.ScanInts
 13     tok := s.Scan()
 14     for tok != scanner.EOF {
 15         fmt.Printf("%d ", tok)
 16         tok = s.Scan()
 17     }
 18     fmt.Println()
 19 }
Run Code Online (Sandbox Code Playgroud)

我使用带有一行整数的文本输入来运行它.但它总是输出-3 -3 ......

以及如何扫描由字符串和一些整数组成的行?遇到新数据类型时更改模式?

包文档:

包扫描仪

用于UTF-8编码文本的通用扫描仪.

但似乎扫描仪不适用于一般用途.

更新的代码:

func main() {
    n := scanf()
    fmt.Println(n)
    fmt.Println(len(n))
}

func scanf() []int {
    nums := new(vector.IntVector)
    reader := bufio.NewReader(os.Stdin)
    str, err := reader.ReadString('\n')
    for err != os.EOF {
        fields := strings.Fields(str)
        for _, f := range fields {
            i, _ := strconv.Atoi(f)
            nums.Push(i)
        }   
        str, err = reader.ReadString('\n')
    }   
    r := make([]int, nums.Len())
    for i := 0; i < nums.Len(); i++ {
        r[i] = nums.At(i)
    }   
    return r
}
Run Code Online (Sandbox Code Playgroud)

改良版:

package main

import (
    "bufio"
    "os"
    "io"
    "fmt"
    "strings"
    "strconv"
    "container/vector"
)

func main() {
    n := fscanf(os.Stdin)
    fmt.Println(len(n), n)
}

func fscanf(in io.Reader) []int {
    var nums vector.IntVector
    reader := bufio.NewReader(in)
    str, err := reader.ReadString('\n')
    for err != os.EOF {
        fields := strings.Fields(str)
        for _, f := range fields {
            if i, err := strconv.Atoi(f); err == nil {
                nums.Push(i)
            }   
        }   
        str, err = reader.ReadString('\n')
    }   
    return nums
}
Run Code Online (Sandbox Code Playgroud)

pet*_*rSO 4

更新后的代码在没有行号的情况下更容易编译,但缺少包和导入语句。

看着你的代码,我注意到了一些事情。这是我对您的代码的修改版本。

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "strconv"
    "strings"
    "container/vector"
)

func main() {
    n := scanf(os.Stdin)
    fmt.Println()
    fmt.Println(len(n), n)
}

func scanf(in io.Reader) []int {
    var nums vector.IntVector
    rd := bufio.NewReader(os.Stdin)
    str, err := rd.ReadString('\n')
    for err != os.EOF {
        fields := strings.Fields(str)
        for _, f := range fields {
            if i, err := strconv.Atoi(f); err == nil {
                nums.Push(i)
            }
        }
        str, err = rd.ReadString('\n')
    }
    return nums
}
Run Code Online (Sandbox Code Playgroud)

我可能想使用任何输入文件scanf(),而不仅仅是Stdin; scanf()以 anio.Reader作为参数。

您写道:nums := new(vector.IntVector),哪里type IntVector []int。这将分配一个名为 的整数切片引用nums并将其初始化为零,然后该new()函数分配一个整数切片引用并将其初始化为零,然后将其分配给nums。我写了: ,它通过简单地分配一个名为 name 的整数切片引用并将其初始化为零var nums vector.IntVector来避免冗余。nums

您没有检查err的值strconv.Atoi(),这意味着无效输入被转换为零值;我跳过它。

要将向量复制到新切片并返回切片,您可以编写:

r := make([]int, nums.Len())
for i := 0; i < nums.Len(); i++ {
    r[i] = nums.At(i)
}
return r
Run Code Online (Sandbox Code Playgroud)

首先,我简单地将其替换为等效方法IntVector.Data()return nums.Data()。然后,我利用这一事实type IntVector []int,通过将其替换为: 来避免分配和复制return nums