寻找相当于scanf的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 }

我用带有整数行的文本输入来运行它。但是它总是输出-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

}

改良版:


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

}


牛魔王的故事
浏览 203回答 3
3回答

慕容708150

没有行号,更新后的代码更容易编译,但是缺少package和import语句。查看您的代码,我注意到了几件事。这是我的代码修订版。package mainimport (&nbsp; &nbsp; "bufio"&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "io"&nbsp; &nbsp; "os"&nbsp; &nbsp; "strconv"&nbsp; &nbsp; "strings"&nbsp; &nbsp; "container/vector")func main() {&nbsp; &nbsp; n := scanf(os.Stdin)&nbsp; &nbsp; fmt.Println()&nbsp; &nbsp; fmt.Println(len(n), n)}func scanf(in io.Reader) []int {&nbsp; &nbsp; var nums vector.IntVector&nbsp; &nbsp; rd := bufio.NewReader(os.Stdin)&nbsp; &nbsp; str, err := rd.ReadString('\n')&nbsp; &nbsp; for err != os.EOF {&nbsp; &nbsp; &nbsp; &nbsp; fields := strings.Fields(str)&nbsp; &nbsp; &nbsp; &nbsp; for _, f := range fields {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if i, err := strconv.Atoi(f); err == nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nums.Push(i)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; str, err = rd.ReadString('\n')&nbsp; &nbsp; }&nbsp; &nbsp; return nums}我可能要使用任何输入文件scanf(),而不仅仅是Stdin;scanf()以aio.Reader作为参数。您写道:nums := new(vector.IntVector),在哪里type IntVector []int。这会分配一个名为的整数切片引用nums并将其初始化为零,然后该new()函数会分配一个整数切片参考并将其初始化为零,然后将其分配给nums。我写道:var nums vector.IntVector,它通过简单地分配一个名为的整数切片引用nums并将其初始化为零来避免冗余。您没有检查的err值strconv.Atoi(),这意味着无效的输入已转换为零值。我跳过它。要将向量从向量复制到新切片并返回该切片,您编写了:r := make([]int, nums.Len())for i := 0; i < nums.Len(); i++ {&nbsp; &nbsp; r[i] = nums.At(i)}return r首先,我简单地将其替换为等效的IntVector.Data()方法:return nums.Data()。然后,我利用了这一事实,type IntVector []int并通过将其替换为来避免分配和复制return nums。

小怪兽爱吃肉

本示例始终一次读取一行,然后将整个行作为字符串返回。如果要从中解析出特定值,则可以。package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "bufio"&nbsp; &nbsp; "os"&nbsp; &nbsp; "strings")func main() {&nbsp; &nbsp; value :=&nbsp; &nbsp; Input("Please enter a value: ")&nbsp; &nbsp; trimmed := strings.TrimSpace(value)&nbsp; &nbsp; fmt.Printf("Hello %s!\n", trimmed)}func Input(str string) string {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; print(str)&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; reader := bufio.NewReader(os.Stdin)&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; input, _ := reader.ReadString('\n')&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; return input&nbsp;}

函数式编程

在对我的回答之一的评论中,您说:根据语言规范:“当通过声明或make()或new()调用分配内存来存储值时,没有提供任何显式初始化,则为该内存提供默认初始化”。那new()有什么意义呢?如果我们运行:package mainimport ("fmt")func main() {&nbsp; &nbsp; var i int&nbsp; &nbsp; var j *int&nbsp; &nbsp; fmt.Println("i (a value) = ", i, "; j (a pointer) = ", j)&nbsp; &nbsp; j = new(int)&nbsp; &nbsp; fmt.Println("i (a value) = ", i, "; j (a pointer) = ", j, "; *j (a value) = ", *j)}该声明var i int分配内存以存储整数值,并将该值初始化为零。该声明var j *int分配内存以存储指向整数值的指针,并将该指针初始化为零(nil指针);没有分配内存来存储整数值。我们看到程序输出类似于:i (a value) =&nbsp; 0 ; j (a pointer) =&nbsp; <nil>内置函数new采用类型T并返回type的值*T。内存被初始化为零值。该语句j = new(int)分配内存以存储整数值,并将该值初始化为零,然后在j中存储指向该整数值的指针。我们看到程序输出类似于:i (a value) =&nbsp; 0 ; j (a pointer) =&nbsp; 0x7fcf913a90f0 ; *j (a value) =&nbsp; 0
打开App,查看更多内容
随时随地看视频慕课网APP