我正在尝试实现一个简化的 Boyer-Moore 字符串搜索算法,该算法从文件中读取其输入文本。该算法要求我从给定的文件位置开始并向后读取其字符,定期向前跳跃预先计算的字符数。跳跃是根据模式的长度和索引计算的,因此我将它们存储为类型 size_t
。我应该使用什么函数来读取特定位置的文件字符,以及应该使用什么类型来存储这些位置?我是 C 语言新手,但我考虑过以下选项:
Fseek
我可以使用fseek
和getc
跳转文件,但这使用 long int
作为其字符索引。我不知道在这个和 size_t
之间进行转换是否安全,无论如何,GNU C 手册 recommends against fseeking text streams出于可移植性的原因。
Fsetpos
这应该更便携,但我不认为我可以用它来向前或向后跳转任意数量的字符。
二进制流
我可以绕过 fseek
将文件作为二进制流打开时出现兼容性问题。但我不知道在处理模式/输入文本时这是否会导致其他兼容性问题,无论如何,这并不能解决 long int
之间的转换问题。和size_t
.
文件描述符
我可以使用文件描述符而不是流。但然后我需要在 size_t
之间进行转换和off_t
,我不知道这有多安全。我也会放弃FILE
的缓冲,我不确定这是否可取。我可以尝试滚动自己的缓冲,或者使用备用库,但这似乎是一个巨大的痛苦。
我的第一个实现将输入文本作为命令行参数传递,因此它根本不处理文件 IO。但我认为这对于大型文本输入来说不能很好地扩展,而且我对文件 IO 的了解越多,我就越感到卡住。你有什么建议?
最佳答案
size_t
⇔ long
转化
如果 long
对于文件偏移量来说足够大,并且您的 size_t
值表示文件偏移量,那么在这两者之间进行转换就没有问题。 (并且不需要显式转换。)
便携性
那么long
实际上对于文件偏移量来说足够大吗?众所周知,long
是 Windows 上的最小大小,即 32 位。即使在 64 位程序中也是如此。因此,如果您计划在使用 fseek
接口(interface)时处理大小为 2 GiB 或更大的文件,则可能会出现可移植性问题。对于较小的文件应该没有问题。
向前或向后跳转任意数量的字符
无论您使用什么界面,Windows 中使用的 CRLF 行结尾都会让您感到困扰。
您很可能可以解决此问题。这取决于您对“角色”的定义,并且可能取决于跳跃需要的精确度。您没有提供足够的信息,我们无法为您提供帮助。
关于c - 我应该使用什么类型/函数来跟踪随机访问的文件位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76459308/