I'm looking for the Go equivalent of scanf(). I tried with following code:
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 }
I run it with input from a text with a line of integers. But it always output -3 -3 ...
And how to scan a line composed of a string and some integers? Changing the mode whenever encounter a new data type?
The Package documentation:
Package scanner
A general-purpose scanner for UTF-8 encoded text.
But it seems that the scanner is not for general use.
Updated code:
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
}
Improved version:
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
}
Scanf() function in Go language scans the input texts which is given in the standard input, reads from there and stores the successive space-separated values into successive arguments as determined by the format. Moreover, this function is defined under the fmt package.
To use this function, you must import the fmt package in your file and access the Scanf function within by using the . notation ( fmt. Scanf ). Here, Scanf is the actual function, while fmt is the Go package that stores the definition of this function.
A return value of 0 means that no fields were assigned.
The scanf() function reads data from the standard input stream stdin into the locations given by each entry in argument-list. Each argument must be a pointer to a variable with a type that corresponds to a type specifier in format-string.
Your updated code was much easier to compile without the line numbers, but it was missing the package and import statements.
Looking at your code, I noticed a few things. Here's my revised version of your code.
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
}
I might want to use any input file for scanf()
, not just Stdin
; scanf()
takes an io.Reader
as a parameter.
You wrote: nums := new(vector.IntVector)
, where type IntVector []int
. This allocates an integer slice reference named nums
and initializes it to zero, then the new()
function allocates an integer slice reference and initializes it to zero, and then assigns it to nums
. I wrote: var nums vector.IntVector
, which avoids the redundancy by simply allocating an integer slice reference named nums
and initializing it to zero.
You didn't check the err
value for strconv.Atoi()
, which meant invalid input was converted to a zero value; I skip it.
To copy from the vector to a new slice and return the slice, you wrote:
r := make([]int, nums.Len())
for i := 0; i < nums.Len(); i++ {
r[i] = nums.At(i)
}
return r
First, I simply replaced that with an equivalent, the IntVector.Data()
method: return nums.Data()
. Then, I took advantage of the fact that type IntVector []int
and avoided the allocation and copy by replacing that by: return nums
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With