fgetc vs getline 或 fgets - 哪个最灵活

fgetc vs getline or fgets - which is most flexible

我正在从常规文件中读取数据,我想知道哪种方式最灵活。

我发现 fgets 和 getline 都读取一行(一个有最大字符数,另一个有动态内存分配)。在 fgets 的情况下,如果行的长度大于给定的大小,则行的其余部分将不会被读取,但会保留在流中的缓冲中。使用 getline,我担心它可能会尝试为超长的行分配一大块内存。

对我来说显而易见的解决方案似乎是转向fgetc,但这带来了一个问题,即调用该函数会多次,从而导致读取过程缓慢。

这种灵活性和效率之间的折衷是不可避免的,还是可以解决的?

很大程度上取决于具体情况。

getline() 而不是 标准 C 库的一部分。它的功能可能不同 - 取决于实现和它遵循的其他标准 - 因此标准 fgetc()/fgets().

的优势

... case between flexibility and efficiency unavoidable, ...

OP 缺少更高的优先级。

  • 功能 - 如果代码无法正确使用所选功能,为什么要使用它?示例:fgets() 和读取 空字符 会产生问题。

  • 清晰度 - 不清晰,感受到后来必须维护代码的可怜灵魂的愤怒。


would allow for the most flexibility. (?)

  • fgetc() 允许在低级别上提供最大的灵活性 - 但使用它来读取行的辅助函数往往会在极端情况下失败。

  • fgets() 在中级允许最大的灵活性 - 仍然必须处理长行和嵌入 空字符 的行,但在至少避免了杂草中的低水平。

  • getline() 在不需要高可移植性并且不担心允许用户淹没资源的风险时很有用。


为了稳健地处理 user/file 输入以读取一行,创建一个包装函数(例如 int my_read_line(size_t buf, char *buf, FILE *f))并仅在用户代码中调用它。然后当出现问题时,可以在本地处理它们,而不管选择的低级输入功能如何。

你提到的三个函数做不同的事情:

  • fgetc()FILE * 描述符中读取单个字符,它缓冲输入,因此,您可以以缓冲方式处理文件,而无需为每个字符进行系统调用.当你的问题能以性格化的方式处理时,那是最好的。
  • fgets()FILE * 描述符中读取一行,这就像调用 fgetc() 来填充您传递给它的字符数组以便逐行读取。如果您的输入行长于您指定的缓冲区大小,它的缺点是会进行部分读取。此函数还缓冲输入数据,因此效率很高。如果您知道您的行将受到限制,那么最好逐行读取您的数据。有时您希望能够以无限行大小的方式处理数据,并且您必须重新设计您的问题以使用可用内存。那么下面这一款估计选的比较好。
  • getline() 这个函数相对较新,不是 ANSI-C,因此您可能将程序移植到缺少它的某些体系结构。它是最灵活的,但代价是效率较低。它需要引用一个指向 realloc() 的指针来填充越来越多的数据。它不会以可能填满系统上所有可用内存为代价来绑定行长度。缓冲区指针和缓冲区的大小都通过引用传递以允许更新它们,因此您知道新字符串的位置和新大小。使用后必须 free()d。

之所以有三个而不是只有一个功能,是因为你对不同的情况有不同的需求,选择最高效的通常是最好的选择。

如果您打算只使用一个,您最终可能会遇到这样一种情况:使用您选为最灵活的功能并不是最好的选择,您可能会失败。