【发布时间】:2011-02-20 22:45:43
【问题描述】:
我想知道如何在 C 中读取某个文件,直到读取到某个字符串或字符数组。我想要做的是,一旦文件命中该字符串,我希望在该点设置位置。我将为此使用 fseek,这不是问题。这只是我无法做到的直到击中某个字符串的读数。我一直在阅读一些功能,但似乎没有任何指导。 Fgets 是最接近这一点的东西,但我不想提供一定数量的要读取的字符,因为我不知道有多少。但是你能给我一些关于如何做到这一点的提示吗?
谢谢!
【问题讨论】:
标签: c
我想知道如何在 C 中读取某个文件,直到读取到某个字符串或字符数组。我想要做的是,一旦文件命中该字符串,我希望在该点设置位置。我将为此使用 fseek,这不是问题。这只是我无法做到的直到击中某个字符串的读数。我一直在阅读一些功能,但似乎没有任何指导。 Fgets 是最接近这一点的东西,但我不想提供一定数量的要读取的字符,因为我不知道有多少。但是你能给我一些关于如何做到这一点的提示吗?
谢谢!
【问题讨论】:
标签: c
有很多高效的字符串搜索算法,每一种都可以用C实现。
http://en.wikipedia.org/wiki/String_searching_algorithm
如果您要查找长度为 N 的字符串,最简单的方法是保留长度为 N 的循环缓冲区,并从文件中一次读取 1 个字节,将其添加到循环缓冲区中。在每个步骤中,您都将缓冲区与您正在搜索的字符串进行比较。它效率极低,但易于编码。
【讨论】:
i 计算您正在读取的字节数,那么buffer[i % N] = new_byte;
没有内置函数可以完全满足您的需求,但有几个选项。
选项一:分块读取数据。您不知道您的数据的确切位置,因此一次读取几 kb 的数据,并在这些块中进行搜索。确保您处理您要查找的字符串跨越块边界的情况!找到字符串后,使用fseek() 将自己定位在字符串的开头。
选项二:内存映射文件并在整个文件上使用memmem()(映射到内存中)。这需要不可移植的调用来设置内存映射,因此您需要了解您的操作系统(或使用像glib 这样的可移植性包装库)。在 32 位机器上,它还将您可以搜索的文件大小限制为几百兆字节。然而,当它是一种选择时,它是一种非常简单和有效的方法。
如果您选择选项一,最棘手的部分将是处理跨块的情况。一种选择是始终在内存中保留两个块,然后重新开始搜索,使其在前一个块结束之前开始(length of target string) - 1 个字节。然后可以使用memmem() 或任何其他string searching algorithm 来完成实际搜索。您还可以将您的搜索转换为DFA(因为它是regular language)并跨块保持当前状态。
【讨论】: