如何在C中打开任何长度的文件?

时间:2011-09-12 20:47:45

标签: c file-io fopen fgets

作为一项学校作业,我的任务是编写一个程序,打开任何文本文件并对文本执行许多操作。必须使用链表加载文本,这意味着包含char指针和指向下一个struct的指针的结构数组。每个结构一行。

但是我在加载文件时遇到了问题。在我实际读取文本之前,似乎必须分配将文本加载到内存中所需的内存。因此,我必须多次打开文件。一旦算出行数,那么每行两次;一旦计算行中的字符然后一次读取它们。打开文件数百次只是为了将其读入内存似乎很荒谬。

显然有更好的方法可以做到这一点,我只是不知道: - )

实施例

  • 可以在不重新打开文件的情况下移动fgetc移动字符的点吗?
  • 可以在“打开”之前检查文件中的行数或字符数吗?
  • 我可以以某种方式读取文件中的行或字符串并将其保存到内存而不分配固定数量的字节吗?

3 个答案:

答案 0 :(得分:3)

不需要多次打开文件,也不需要多次传递它。

查看POSIX getline()函数。它将行读入分配的空间。您可以使用它来读取行,然后复制链接列表的结果。

没有必要使用链表来提前知道有多少行;这是列表的优势。

因此,代码可以通过一次完成。即使您不能使用getline(),也可以使用fgets()并监视它是否每次都读取到行尾,如果不是,您可以分配(并重新分配)空间来保存根据需要行malloc()realloc(),最后free()来自<stdlib.h>

如果你采用我建议的方法,你的具体问题在很大程度上是无关紧要的,但是:

  • 使用fseek()(以及在extremis rewind()中)将移动读指针(对于fgetc()和所有其他函数),除非'file'不支持搜索(例如,作为标准输入提供的管道。

  • 可以使用stat()fstat()或变体来确定字符。除非通过阅读文件,否则无法确定行。

  • 由于文件大小可能从零字节到千兆字节,因此没有一种合理的方法可以进行固定大小的分配。使用malloc()等人,你几乎被迫进入动态内存分配。 (在幕后,getline()使用malloc()realloc()。)

答案 1 :(得分:1)

如果没有实际遍历文件,则无法计算文件中的行数。你可以得到总文件大小,但这不是什么意思。使用链接的行列表的想法是您一次对文件进行一行操作。您不需要提前阅读任何内容。如果您还没有读取整个文件,请读取一行,将其添加到链接列表末尾的自己的节点,然后移动到下一行。

答案 2 :(得分:0)

关于第一个问题:您可以使用fseek()函数更改正在读取的文件中的位置。

有几种方法可以做到这一点。例如,你可以有一个固定大小的缓冲区,用文件中的字节填充它,从缓冲区复制行到列表,再次填充缓冲区等等。