Go search is equivalent to scanf

I am looking for the Go equivalent for scanf (). I tried with the 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 start it by inputting text with an integer. But he always displays -3 -3 ...

And how to scan a string consisting of a string and some integers? Change in mode when a new data type occurs?

Package Documentation:

Packet scanner

Universal scanner for UTF-8 encoded text.

But it looks like the scanner is not intended 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 } 

Enhanced 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 } 
+6
go
source share
5 answers

Your updated code was much easier to compile without line numbers, but it lacked package and import instructions.

Looking at my code, I noticed a few things. Here is 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 can use any input file for scanf() , not just Stdin ; scanf() takes io.Reader as a parameter.

You wrote: nums := new(vector.IntVector) , where type IntVector []int . This selects the whole slice reference called nums and initializes it to zero, then the new() function selects the whole slice reference and initializes it to zero, and then assigns it nums . I wrote: var nums vector.IntVector , which avoids redundancy by simply highlighting a link to an integer slice named nums and initializing it to zero.

You did not mark err for strconv.Atoi() , which meant that invalid input was converted to a null value; I missed it.

To copy from a 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 just replaced this with the equivalent IntVector.Data() method: return nums.Data() . Then I took advantage of the fact that type IntVector []int and avoided highlighting and copying by replacing it with: return nums .

+4
source share

Although it can be used for other purposes, the scanner package is designed to scan Go text. Ints (-123), Chars ('c'), Strings ("str"), etc. Are Go language markers.

 package main import ( "fmt" "os" "scanner" "strconv" ) func main() { var s scanner.Scanner s.Init(os.Stdin) s.Error = func(s *scanner.Scanner, msg string) { fmt.Println("scan error", msg) } s.Mode = scanner.ScanInts | scanner.ScanStrings | scanner.ScanRawStrings for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { txt := s.TokenText() fmt.Print("token:", tok, "text:", txt) switch tok { case scanner.Int: si, err := strconv.Atoi64(txt) if err == nil { fmt.Print(" integer: ", si) } case scanner.String, scanner.RawString: fmt.Print(" string: ", txt) default: if tok >= 0 { fmt.Print(" unicode: ", "rune = ", tok) } else { fmt.Print(" ERROR") } } fmt.Println() } } 
0
source share

This example is always read in a string at a time and returns the entire string as a string. If you want to parse specific values ​​from it, you can.

 package main import ( "fmt" "bufio" "os" "strings" ) func main() { value := Input("Please enter a value: ") trimmed := strings.TrimSpace(value) fmt.Printf("Hello %s!\n", trimmed) } func Input(str string) string { print(str) reader := bufio.NewReader(os.Stdin) input, _ := reader.ReadString('\n') return input } 
0
source share

In a comment on one of my answers, you said:

From the language specification: "When memory is allocated for storing a value, either through an declaration, either by making () or new (), and there is no explicit initialization, the memory is set to default initialization." Then what is the point of new ()?

If we run:

 package main import ("fmt") func main() { var i int var j *int fmt.Println("i (a value) = ", i, "; j (a pointer) = ", j) j = new(int) fmt.Println("i (a value) = ", i, "; j (a pointer) = ", j, "; *j (a value) = ", *j) } 

The declaration var i int allocates memory for storing an integer value and initializes the value to zero. The declaration var j *int allocates memory to hold a pointer to an integer value and initializes a pointer to zero (pointer nil); no memory is allocated for storing an integer value. We see that the output of the program is similar to:

 i (a value) = 0 ; j (a pointer) = <nil> 

The built-in function new takes type T and returns a value of type *T The memory is initialized to zero values. The operator j = new(int) allocates memory for storing an integer value and initializes the value to zero, then it stores a pointer to this integer value in j. We see that the output of the program is similar to:

 i (a value) = 0 ; j (a pointer) = 0x7fcf913a90f0 ; *j (a value) = 0 
0
source share

The latest version of Go (2010-05-27) added two functions to the fmt package: Scan() and Scanln() . They do not take a string of patterns. as in C, but instead checks the type of arguments.

 package main import ( "fmt" "os" "container/vector" ) func main() { numbers := new(vector.IntVector) var number int n, err := fmt.Scan(os.Stdin, &number) for n == 1 && err == nil { numbers.Push(number) n, err = fmt.Scan(os.Stdin, &number) } fmt.Printf("%v\n", numbers.Data()) } 
0
source share

All Articles