在线文档教程
Ruby 2.4

Scanf

Scanf模块

scanf for Ruby

描述

scanf是C函数scanf(3)的一个实现,根据Ruby兼容性的需要进行了修改。

提供的方法是String#scanf,IO#scanf和Kernel#scanf。内核#scanf是STDIN.scanf的一个包装。IO#scanf可用于任何IO流,包括文件句柄和套接字。可以使用或不使用块来调用scanf。

Scanf根据格式扫描输入字符串或流,如转换中所述,并返回格式和输入之间的匹配数组。格式在字符串中定义,与Kernel#printf和Kernel#sprintf中使用的格式类似(尽管不完全相同)。

格式可以包含转换说明符,它告诉scanf每个特定的匹配子字符串应该被转换为什么形式(类型)(例如,十进制整数,浮点数,字符串等)。匹配和转换从左到右发生,并且转换本身作为数组返回。

格式字符串也可能包含除转换说明符以外的字符。格式字符串中的空格(空格,制表符或换行符)与输入中的任意数量的空格(包括none)匹配。其他只匹配自身。

当任何输入字符与格式字符串中的规格不匹配,或者输入耗尽时,或格式字符串中的所有内容都匹配时,扫描将停止,并且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")

Block用法

当使用块调用时,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应接下来扫描的信息(字符串,十进制数,单个字符等)。

%和转换之间可能有一个可选的最大字段宽度,用十进制整数表示。如果没有给出宽度,则使用缺省值'infinity'(除了%c说明符;参见下文)。否则,如果给定转换的字段宽度为n,则在处理该转换时最多会扫描n个字符。在转换开始之前,大多数转换会跳过输入字符串中的空白区域; 此白色空间不计入字段宽度。

以下转换可用。

%

匹配文字%'。 也就是说,格式字符串中的%%'匹配单个输入'%'字符。 没有转换完成,并且返回数组中不包含结果'%'。

d

匹配可选的带符号的十进制整数。

u

与d相同。

i

匹配一个可选的有符号整数。 如果以0x'或0xX开始,则以16为基数读取整数,如果以“0”开始则以8为基数读取整数,否则以基数10读取。 只有对应于该基地的字符才被识别。

o

匹配一个可选的八进制整数。

x, X

匹配一个可选的有符号十六进制整数,

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

匹配一个可选的带符号的浮点数。

s

匹配一系列非空白字符。输入字符串在空白处或最大字段宽度处停止,以先发生者为准。

c

如果指定了字段宽度n,则匹配单个字符或n个字符序列。领先的白色空间通常会被忽略。要首先跳过空格,请使用格式中的显式空格。

[

匹配来自指定的一组接受字符的非空字符序列。领先的白色空间通常会被忽略。这个括号内的子表达式在Ruby正则表达式中被完全解释为一个字符类。(实际上,它是按照原样放置在正则表达式中的。)与输入字符串的匹配以不在(或带有旋转曲线)中的字符的外观结束,或者当字段宽度用完时, 以先到者为准。

分配抑制

要求特定匹配发生,但不在返回数组中包含结果,请将分配抑制标志(即星号('*'))紧接在格式说明符的前导'%'之后(紧挨着字段宽度,如果有的话)。

用于Ruby的scanf与C中的scanf相比较

用于Ruby的scanf基于C函数scanf(3),但有修改,主要由语言之间的根本区别决定。

未实现的标志和说明符

  • 在scanf for Ruby中实现的唯一标志是' *'(忽略即将到来的转换)。在scanf(3)的C版本中可用的许多标志都与即将到来的指针参数的类型有关,并且在Ruby中没有意义。

  • n说明符(目前在下一个指针中消耗的字符数量)未实现。

  • p说明符(匹配指针值)未实现。

改变说明符

o, u, x, X

在Ruby的scanf中,所有这些说明符都会扫描一个可选的有符号整数,而不是像C对象那样的无符号整数。

返回值

scanf for Ruby返回成功转换数组,而scanf(3)返回成功完成的转换数。(有关scanf for Ruby返回值的更多详细信息,请参见下文。)

返回值

如果没有块,scanf将返回一个包含所有已找到的转换的数组。如果没有找到,scanf将返回一个空数组。不成功的匹配永远不会被忽略,而是始终表示扫描操作结束。如果第一次不成功的匹配发生在一次或多次成功的匹配之后,返回的数组将包含那些成功匹配的结果。

用一个块scanf返回一个来自块的'map'类转换数组 - 也就是说,一个数组反映每个块产生的迭代scanf操作产生的结果。(请参阅上面的“阻止使用”。)

目前的限制和错误

在Windows下使用IO#scanf时,请确保以二进制模式打开文件:

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

这样scanf 就可以正确地跟踪字符。

对字符类的支持是相当完整的(因为它本质上是对Ruby的字符类的正则表达式处理的捎带),但是用户被告知字符类测试并不是详尽无遗,并且他们应该谨慎地使用任何更多的复杂的和/或神秘的人物类成语。

错误和错误报告

针对Ruby的scanf基于C ++ scanf实现和文档的混合,而不是单一的规范描述。对于出现在其他scanfs中的特性和行为建议,在Ruby中会很有意义,对于可疑行为和/或错误的报告也是如此。(有关电子邮件地址,请参阅上面的“信用和确认信息”。)