Поиск Идет эквивалентный из scanf

Я ищу Движение, эквивалентное из scanf (). Я попробовал следующим кодом:

  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
}
6
задан hannson 19 March 2010 в 16:00
поделиться

5 ответов

Ваш обновленный код был намного легче скомпилировать без номеров строк, но в нем отсутствовали операторы package и import.

Глядя на ваш код, я заметил несколько вещей. Вот моя исправленная версия вашего кода.

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
}

Я мог бы использовать любой входной файл для scanf () , а не только Stdin ; scanf () принимает в качестве параметра io.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++ {
    r[i] = nums.At(i)
}
return r

Во-первых, я просто заменил его на эквивалент, метод IntVector.Data () : вернуть nums.Data () . Затем я воспользовался тем фактом, что тип IntVector [] int избежал выделения и копирования, заменив это на: return nums .

4
ответ дан 17 December 2019 в 07:03
поделиться

Хотя его можно использовать для других целей, пакет сканера предназначен для сканирования текста программы Go. Ints (-123), Chars ('c'), Strings ("str") и т. Д. Являются типами токенов языка Go.

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
ответ дан 17 December 2019 в 07:03
поделиться

В комментарии к одному из моих ответов вы сказали:

Из спецификации языка: "Когда {{ 1}} память выделяется для хранения значения либо посредством объявления, либо вызова make () или new (), и явная инициализация не предоставляется, память { {1}} получает инициализацию по умолчанию ". Тогда в чем смысл new ()?

Если мы запустим:

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)
}

Объявление var i int выделяет память для хранения целочисленное значение и инициализирует значение нулем. Объявление var j * int выделяет память для хранения указателя на целочисленное значение и инициализирует указатель нулем (указатель nil); для хранения целочисленного значения память не выделяется. Мы видим вывод программы, подобный следующему:

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

Встроенная функция new принимает тип T и возвращает значение типа * T .Память инициализируется нулевыми значениями. Оператор j = new (int) выделяет память для хранения целочисленного значения и инициализирует значение нулем, а затем сохраняет указатель на это целочисленное значение в j. Мы видим вывод программы, подобный следующему:

i (a value) =  0 ; j (a pointer) =  0x7fcf913a90f0 ; *j (a value) =  0
0
ответ дан 17 December 2019 в 07:03
поделиться

В этом примере всегда выполняется чтение по строке за раз и возвращается вся строка в виде строки. Если вы хотите извлечь из него определенные значения, вы можете.

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
ответ дан 17 December 2019 в 07:03
поделиться

В последней версии Go (27.05.2010) в пакет fmt добавлены две функции: Scan () и Scanln () . Они не берут никаких шаблонных строк. как в C, но вместо этого проверяет тип аргументов.

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
ответ дан 17 December 2019 в 07:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: