Функция fmt.Fscanf

Функция fmt.Fscanf считывает данные из переданного io.Reader в соответствии со строкой формата и сохраняет результат в аргументы, переданные по указателям. В первый параметр мы передаем интерфейс io.Reader (например, *os.File или strings.Reader), во второй параметр мы передаем строку формата, в третий и последующие параметры мы передаем указатели на переменные, в которые необходимо сохранить считанные данные. Возвращает функция количество успешно обработанных элементов и ошибку, если она произошла.

Синтаксис

gon, err := fmt.Fscanf(r, format, &a, &b, ...)

Где r - источник данных, format - строка формата, а &a, &b - указатели на переменные для сохранения.

Пример

Давайте считаем строку и целое число из строки-источника:

gopackage main

import (
  "fmt"
  "strings"
)

func main() {
  src := strings.NewReader("Alice 30")
  var name string
  var age int

  n, err := fmt.Fscanf(src, "%s %d", &name, &age)
  if err != nil {
    fmt.Println(err)
    return
  }

  fmt.Printf("Считано: %d элементов\n", n)
  fmt.Printf("name: %s, age: %d\n", name, age)
}

Результат выполнения кода:

go"Считано: 2 элементов"
"name: Alice, age: 30"

Обратите внимание, что в примере выше мы использовали strings.NewReader для создания источника данных. Функция успешно распарсила строку и число по формату.

Пример

Теперь давайте считаем значения разных типов из файла. Создадим строку с данными и прочитаем их:

gopackage main

import (
  "fmt"
  "strings"
)

func main() {
  data := strings.NewReader("3.14 42 true hello")
  var pi float64
  var num int
  var flag bool
  var word string

  n, err := fmt.Fscanf(data, "%f %d %t %s", &pi, &num, &flag, &word)
  if err != nil {
    fmt.Println(err)
    return
  }

  fmt.Printf("Количество: %d\n", n)
  fmt.Printf("pi: %f, num: %d, flag: %t, word: %s\n", pi, num, flag, word)
}

Результат выполнения кода:

go"Количество: 4"
"pi: 3.140000, num: 42, flag: true, word: hello"

Функция корректно преобразовала строковые данные в соответствующие типы благодаря указанной строке формата.

Пример

Продемонстрируем обработку ошибки, если данные не соответствуют формату:

gopackage main

import (
  "fmt"
  "strings"
)

func main() {
  src := strings.NewReader("abc 123")
  var num int

  n, err := fmt.Fscanf(src, "%d", &num)
  if err != nil {
    fmt.Printf("Ошибка: %v\n", err)
    fmt.Printf("Считано элементов: %d\n", n)
    return
  }

  fmt.Printf("num: %d\n", num)
}

Результат выполнения кода:

go"Ошибка: expected integer"
"Считано элементов: 0"

Как видно из примера, при несоответствии формата данных функция возвращает ошибку и ноль успешно считанных элементов.

Смотрите также

  • функцию fmt.Fscan,
    которая считывает данные из io.Reader без учета формата
  • функцию fmt.Fscanln,
    которая считывает данные до перевода строки
  • функцию fmt.Sscanf,
    которая сканирует данные из строки по формату
  • функцию fmt.Fprintf,
    которая форматирует вывод в io.Writer