Spec-Zone.ru › Ruby 2.4

модуль Scanf

scanf для Ruby

Описание

scanf — это реализация функции C scanf(3), изменённая по мере необходимости для совместимости с Ruby.

предоставленные методы — String#scanf, IO#scanf и Kernel#scanf. Kernel#scanf — это оболочка вокруг STDIN.scanf. IO#scanf может использоваться с любым потоком IO, включая дескрипторы файлов и сокеты. scanf может вызываться как с блоком, так и без него.

Scanf анализирует строку или поток ввода в соответствии с заданным форматом, как описано ниже в Раздела «Преобразования», и возвращает массив совпадений между форматом и вводом. Формат определён в строке и похож (хотя и не идентичен) на форматы, используемые в Kernel#printf и Kernel#sprintf.

Формат может содержать спецификаторы преобразования, которые указывают scanf, в какой форме (тип) должна быть преобразована каждая конкретная совпавшая подстрока (например, целое десятичное число, число с плавающей точкой, строка-литераль и т. д.). Совпадения и преобразования происходят слева направо, а сами преобразования возвращаются в виде массива.

Строка формата может также содержать символы, отличные от символов в спецификаторах преобразования. Пробелы (пробелы, табуляции или переводы строк) в строке формата соответствуют любому количеству пробелов, включая отсутствие пробелов, в вводе. Всё остальное соответствует только самому себе.

Анализ прекращается, и scanf возвращает значение, когда любой символ ввода не соответствует спецификациям в строке формата, или когда вход исчерпан, или когда всё в строке формата было сопоставлено. Все найденные совпадения до точки остановки возвращаются в массиве возврата (или передаются в блок, если был задан блок).

Базовое использование

require 'scanf'

# String#scanf and IO#scanf take a single argument, the format string
array = a_string.scanf("%d%s")
array = an_io.scanf("%d%s")

# Kernel#scanf reads from STDIN
array = scanf("%d%s")

Использование с блоком

При вызове с блоком scanf продолжает анализировать вход, циклически возвращаясь к началу строки формата, и каждый раз, когда строка формата совпадает (включая частичные совпадения, но не включая полные неудачи), возвращает в блок новый массив преобразований. Фактическое возвращаемое значение scanf при вызове с блоком — это массив, содержащий результаты всех выполнений блока.

str = "123 abc 456 def 789 ghi"
str.scanf("%d%s") { |num,str| [ num * 2, str.upcase ] }
# => [[246, "ABC"], [912, "DEF"], [1578, "GHI"]]

Преобразования

Единственный аргумент scanf — это строка формата, которая обычно включает один или несколько спецификаторов преобразования. Спецификаторы преобразования начинаются с символа процента ('%') и содержат информацию о том, что scanf должен проанализировать дальше (строка, десятичное число, одиночный символ и т. д.).

Может быть необязательная максимальная ширина поля, выраженная как десятичное целое число, между символом '%' и преобразованием. Если ширина не задана, используется значение по умолчанию — «бесконечность» (за исключением спецификатора %c; см. ниже). В противном случае, если ширина поля для данного преобразования равна n, при обработке этого преобразования анализируется не более n символов. Перед началом преобразования большинство преобразований пропускают пробелы в строке ввода; эти пробелы не учитываются в ширине поля.

Доступны следующие преобразования.

%

Соответствует литеральной «%». То есть, «%%» в строке формата соответствует одиночному символу «%» ввода. Никакого преобразования не выполняется, и результат «%» не включается в массив возврата.

d

Соответствует необязательному со знаком целому десятичному числу.

u

То же, что и d.

i

Соответствует необязательному со знаком целому числу. Целое число считывается в 16-ричной системе счисления, если оно начинается с «0x» или «0X», в 8-ричной системе счисления, если оно начинается с «0», и в 10-ричной системе счисления в противном случае. Признаются только символы, соответствующие основанию.

o

Соответствует необязательному со знаком целому числу в 8-ричной системе счисления.

x, X

Соответствует необязательному со знаком целому числу в 16-ричной системе счисления.

a, e, f, g, A, E, F, G

Соответствует необязательному со знаком числу с плавающей точкой.

s

Соответствует последовательности символов без пробелов. Строка ввода заканчивается на пробеле или на максимальной ширине поля, в зависимости от того, что произойдёт раньше.

c

Соответствует одному символу или последовательности из n символов, если задана ширина поля n. Обычный пропуск начальных пробелов подавлен. Чтобы сначала пропустить пробелы, используйте явный пробел в формате.

[

Соответствует непустой последовательности символов из указанного набора допустимых символов. Обычный пропуск начальных пробелов подавлен. Это скобочное подвыражение интерпретируется точно так же, как класс символов в регулярном выражении Ruby. (На самом деле, оно помещается как есть в регулярное выражение.) Сопоставление со строкой ввода заканчивается появлением символа, не входящего в (или, с крышкой, в) набор, или при достижении ширины поля, в зависимости от того, что произойдёт раньше.

Подавление присваивания

Чтобы потребовать, чтобы определённое совпадение произошло, но не включать результат в массив возврата, используйте флаг подавления присваивания, который является символом звёздочки ('*'), сразу после ведущего символа '%' спецификатора формата (непосредственно перед шириной поля, если она задана).

Сравнение scanf для Ruby с scanf в C

scanf для Ruby основан на функции C scanf(3), но с модификациями, продиктованными в основном различиями между языками.

Не реализованные флаги и спецификаторы

  • Единственный реализованный в scanf для Ruby флаг — '*' (пропустить следующее преобразование). Многие флаги, доступные в C-версиях scanf(3), связаны с типом следующих аргументов указателя и бессмысленны в Ruby.

  • Спецификатор n (сохранить количество потреблённых символов до сих пор в следующем указателе) не реализован.

  • Спецификатор p (сопоставить значение указателя) не реализован.

Изменённые спецификаторы

o, u, x, X

В scanf для Ruby все эти спецификаторы анализируют необязательно со знаком целое число, а не беззнаковое целое число, как их C-аналоги.

Значения возврата

scanf для Ruby возвращает массив успешных преобразований, тогда как scanf(3) возвращает количество успешно завершённых преобразований. (См. ниже подробности о значениях возврата scanf для Ruby.)

Значения возврата

Без блока scanf возвращает массив, содержащий все найденные им преобразования. Если преобразования не найдены, scanf вернёт пустой массив. Неудачное совпадение никогда не игнорируется, а вместо этого всегда сигнализирует об окончании операции анализа. Если первое неудачное совпадение происходит после одного или нескольких успешных совпадений, возвращаемый массив будет содержать результаты этих успешных совпадений.

С блоком scanf возвращает массив преобразований из блока — то есть массив, отражающий, что блок сделал с каждым результатом, полученным из итеративного процесса анализа scanf. (См. «Использование с блоком» выше.)

Текущие ограничения и ошибки

При использовании IO#scanf в Windows убедитесь, что вы открываете файлы в двоичном режиме:

File.open("filename", "rb")

чтобы scanf мог правильно отслеживать символы.

Поддержка классов символов достаточно полная (поскольку она по сути опирается на обработку классов символов регулярных выражений Ruby), но пользователям рекомендуется соблюдать осторожность при использовании более сложных и/или загадочных конструкций с классами символов.

Лицензия и авторские права

Авторские права

© 2002-2003 David Alan Black

Лицензия

Распространяется на тех же лицензионных условиях, что и сам Ruby

Отказ от гарантии

Данное программное обеспечение предоставляется «как есть» без каких-либо явных или подразумеваемых гарантий, включая, помимо прочего, подразумеваемые гарантии товарной пригодности и пригодности для определённой цели.

Авторы и благодарности

scanf был разработан как основная задача Austin Ruby Codefest (Остин, Техас, август 2002 г.).

Главный автор

David Alan Black (dblack@superlink.net)

Соавтор

Hal Fulton (hal9000@hypermetrics.com)

Участники проекта

Nolan Darilek, Jason Johnston

Благодарим Hal Fulton за организацию Codefest.

Благодарим Matz за предложения по проектированию класса.

Благодарим Gavin Sinclair за отзывы по документации.

Текст некоторых разделов этого документа, особенно разделов «Описание» и «Преобразования» выше, был адаптирован из справки по программированию для Linux manpage для scanf(3) от 01 ноября 1995 г.

Ошибки и сообщения об ошибках

scanf для Ruby основан на некотором смешении реализаций и документации C scanf, а не на одном каноническом описании. Предложения по функциям и поведению, которые присутствуют в других scanf и были бы полезны в Ruby, приветствуются, как и сообщения о подозрительном поведении и/или ошибках. (Пожалуйста, обратитесь к «Авторам и благодарностям» выше для адресов электронной почты.)

Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API