小编Jul*_*erg的帖子

C:使用fread()/ fgets()而不是fgetc()(块I/O与字符I/O)逐行读取文本文件(使用可变长度行)

是否有getline使用fread(块I/O)而不是fgetc(字符I/O)的函数?

通过字符读取文件字符会有性能损失fgetc.我们认为为了提高性能,我们可以fread在内循环中使用块读取getline.然而,这引入了读取超过行尾的潜在不期望的效果.至少,这需要实现getline跟踪文件的"未读"部分,这需要超出ANSI C FILE语义的抽象.这不是我们想要自己实现的东西!

我们已经分析了我们的应用程序,并且由于我们逐个字符地消耗大型文件,因此性能缓慢fgetc.通过比较,其余的开销实际上具有微不足道的成本.我们总是按顺序读取文件的每一行,从头到尾,我们可以在读取期间锁定整个文件.这可能使fread基于getline更容易实现.

那么,是否存在getline使用fread(块I/O)而不是fgetc(字符I/O)的函数?我们非常肯定它确实如此,但如果没有,我们应该如何实施呢?

更新发现了一篇有用的文章,在C中处理用户输入,由Paul Hsieh撰写.这是一种fgetc基于方法的方法,但它对替代方案进行了有趣的讨论(从有多糟糕开始gets,然后讨论fgets):

另一方面,C程序员(甚至那些经验丰富的人)的常见反驳是说fgets()应该用作替代方案.当然,fgets()本身并不能真正处理用户输入.除了具有奇怪的字符串终止条件(在遇到\n或EOF,但不是\ 0时),当缓冲区达到容量时选择终止的机制是简单地突然停止fgets()操作并且\ 0终止它.因此,如果用户输入超过预分配缓冲区的长度,则fgets()返回部分结果.处理这个程序员有几个选择; 1)简单地处理截断的用户输入(没有办法向用户反馈输入已被截断,而他们提供输入)2)模拟可增长的字符数组并通过连续调用fgets()填充它.对于可变长度的用户输入,第一种解决方案几乎总是一个非常糟糕的解决方案,因为缓冲区在大多数情况下不可避免地会过大,因为它试图捕获太多普通情况,而对于异常情况则太小.第二种解决方案很好,只是正确实施可能很复杂.两者都不涉及fgets在'\ 0'方面奇怪行为.

练习留给读者:为了确定通过调用fgets()确实读取了多少字节,可以尝试通过扫描(就像它一样)来搜索'\n'并跳过任何'\ 0'而不超过传递给fgets()的大小.解释为什么这对于流的最后一行是不够的.ftell()的弱点是什么阻止它完全解决这个问题?

练习留给读者:通过在每次调用fgets()之间用非零值覆盖整个缓冲区来解决确定fgets()消耗的数据长度的问题.

因此,使用fgets(),我们可以选择编写大量代码并使用与C库的其余部分不一致或具有任意截止的行终止条件.如果这还不够好,那么我们还剩下什么?scanf()以无法分离的方式将解析与读取混合,并且 …

c file-io fgets fread

6
推荐指数
1
解决办法
2万
查看次数

标签 统计

c ×1

fgets ×1

file-io ×1

fread ×1