我正在编写一个程序来逐行读取文件 . 我知道fgets()将读取新行,n-1个字符或EOF . 令我困惑的是fgets()如何知道前进到新行/它在文件中的位置?
为了更清楚,我知道在Java中你必须明确告诉扫描仪阅读下一行 . 但是在C语言中,我只是将fgets()置于while循环中并相信这是它的工作 .
我怎么能在逻辑上向我保证fgets()实际上是在推进到下一行,而不是在while循环中一遍又一遍地读同一行(是的,我知道我可以打印出来的东西)?
fgets() 的语义非常简单:从 FILE* 流指针读取字节,直到:
fgets()
FILE*
目标数组已满(已读取 n-1 个字节并将其存储到其中) .
n-1
从流中读取换行并存储到目标数组中 .
已到达文件末尾或发生读取错误( fgetc() 调用返回 EOF 或等效) . 在 fgets() 返回 NULL 之后,可以通过调用 ferr() 和/或_1786132来区分文件结束和读取错误条件 .
fgetc()
EOF
NULL
ferr()
除非立即到达文件末尾( fgets() 返回 NULL )或缓冲区大小指定为大小为0,否则在从流中读取的字节之后始终将空终止符存储到数组中 .
fgets() 的行为就像使用 fgetc() 一次读取一个字节流一样 .
fgets() 使用从流中读取的字节并将它们存储到目标数组中 . 它不能再次读取相同的字节,除非您使用 rewind() , fseek() 或 fsetpos() 明确地向后搜索流,如果流支持搜索的话 . 附加到常规文件的流通常支持搜索,但是以文本模式打开的文件需要在某些系统上进行特定处理,尤其是Microsoft Windows . 另请注意,在实际流中的任何字节之前, fgets() 将读回一个带回 ungetc() 的流的字节 .
rewind()
fseek()
fsetpos()
ungetc()
fgets() 将换行符存储到目标数组中,如果该行足够短以适应空终止符之前的数组 .
如果行超出目标数组中的可用空间,则 fgets() 将长行分成较小的块 . 处理长行很棘手且容易出错 . 请注意,当 fgets() 由于目标数组中的空间不足而读取部分行时,对 fgets() 的下一次调用将继续从上一次调用停止的点处的同一行读取 .
如果从 fgets() 返回时,目标数组不以换行符结束,则发生以下情况之一:
当前行太长,只从流中读取数组中适合的字节数 .
行读取是文件中的最后一行,文件不以换行符结束 .
从文件中读取了一个空字节 .
错误处理这些情况可能会导致潜在的不确定行为和/或可利用的漏洞 .
1 回答
fgets()
的语义非常简单:从FILE*
流指针读取字节,直到:目标数组已满(已读取
n-1
个字节并将其存储到其中) .从流中读取换行并存储到目标数组中 .
已到达文件末尾或发生读取错误(
fgetc()
调用返回EOF
或等效) . 在fgets()
返回NULL
之后,可以通过调用ferr()
和/或_1786132来区分文件结束和读取错误条件 .除非立即到达文件末尾(
fgets()
返回NULL
)或缓冲区大小指定为大小为0,否则在从流中读取的字节之后始终将空终止符存储到数组中 .fgets()
的行为就像使用fgetc()
一次读取一个字节流一样 .fgets()
使用从流中读取的字节并将它们存储到目标数组中 . 它不能再次读取相同的字节,除非您使用rewind()
,fseek()
或fsetpos()
明确地向后搜索流,如果流支持搜索的话 . 附加到常规文件的流通常支持搜索,但是以文本模式打开的文件需要在某些系统上进行特定处理,尤其是Microsoft Windows . 另请注意,在实际流中的任何字节之前,fgets()
将读回一个带回ungetc()
的流的字节 .fgets()
将换行符存储到目标数组中,如果该行足够短以适应空终止符之前的数组 .如果行超出目标数组中的可用空间,则
fgets()
将长行分成较小的块 . 处理长行很棘手且容易出错 . 请注意,当fgets()
由于目标数组中的空间不足而读取部分行时,对fgets()
的下一次调用将继续从上一次调用停止的点处的同一行读取 .如果从
fgets()
返回时,目标数组不以换行符结束,则发生以下情况之一:当前行太长,只从流中读取数组中适合的字节数 .
行读取是文件中的最后一行,文件不以换行符结束 .
从文件中读取了一个空字节 .
错误处理这些情况可能会导致潜在的不确定行为和/或可利用的漏洞 .