C fgets与fgetc的阅读线

时间:2011-03-03 20:58:03

标签: c io stdio fgets fgetc

我需要读取一行文本(以换行符结尾),而不对长度做出假设。所以我现在面对各种可能性:

  • 使用fgets并每次检查最后一个字符是否为换行符并连续附加到缓冲区
  • 使用fgetc和偶尔realloc缓冲区
  • 读取每个字符

Intuition告诉我fgetc变体可能会变慢,但是我再也看不到fgets如何在不检查每个角色的情况下做到这一点(我的直觉也并非总是那么好)。线条非常大,因此性能很重要。

我想知道每种方法的优缺点。提前谢谢。

5 个答案:

答案 0 :(得分:2)

您的环境是否提供getline(3)功能?如果是这样,我会说那样做。

我看到的最大优点是它本身分配了缓冲区(如果你想要的话),如果它太小,你将传入的缓冲区realloc()。 (所以这意味着你需要传递从malloc()获得的东西。

这消除了fgets / fgetc的一些痛苦,你可以希望那些编写实现它的C库的人都会把它变得高效。

Bonus:Linux上的手册页有一个很好的例子,说明如何以有效的方式使用它。

答案 1 :(得分:2)

我建议使用fgets()加上动态内存分配 - 或者您可以调查POSIX 2008标准中getline()的接口,并且可以在更新的Linux机器上使用。这为你做了内存分配。您需要密切关注缓冲区长度及其地址 - 因此您甚至可以创建一个处理信息的结构。

尽管fgetc()也有效,但它有点吝啬 - 但只是略有不同。在封面下方,它使用与fgets()相同的机制。内部可能能够利用更快的操作 - 类似于strchr() - 当您直接致电fgetc()时无法使用。

答案 2 :(得分:2)

如果效果对您很重要,通常需要拨打getc而不是fgetc。该标准试图使getc更容易实现为宏,以避免函数调用开销。

过去,处理的主要问题可能是你分配缓冲区的策略。大多数人使用固定增量(例如,当我们用完空间时,分配另外128个字节)。我建议改为使用常量因子,所以如果空间不足,请分配一个缓冲区,比如前一个大小的1 1/2倍。

特别是当getc作为宏实现时,getcfgets之间的差异通常非常小,因此您最好专注于其他问题。

答案 3 :(得分:0)

如果你可以设置一个最大行长度,即使是一个大行长度,那么一个fgets就可以了。如果没有,多个fgets调用仍然会比多个fgetc调用更快,因为后者的开销会更大。

但更好的答案是,除非必须,否则不值得担心性能差异。如果fgetc足够快,那有什么关系?

答案 4 :(得分:0)

我会分配一个大缓冲区,然后使用fgets,检查,重新分配和重复,如果你还没有读到行的末尾。

每次你读(通过fgetc或fgets)你正在进行系统调用,这需要花费时间,你想要最小化发生的次数,所以调用fgets更少次并在内存中迭代更快。

如果您正在阅读文件,则mmap()在文件中是另一种选择。