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应接下来扫描的信息(字符串,十进制数,单个字符等)。
%和转换之间可能有一个可选的最大字段宽度,用十进制整数表示。如果没有给出宽度,则使用缺省值'in
fin
ity'(除了%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中会很有意义,对于可疑行为和/或错误的报告也是如此。(有关电子邮件地址,请参阅上面的“信用和确认信息”。)