如何在C语言中使用fgets()函数获取文件中的特定行?

8

所以,我正在尝试在C语言中查找一种方法来fgets()读取文本文件中的特定行,将该行内容复制到更永久的缓冲区中:

实际上,我想知道是否有一种方法可以不使用类似以下代码的方式来完成:

FILE *fp;
fp = fopen(filename, "r");

char line[256];
char * buffer;
int targetline = 10;
while( targetline > 0)
{
    fgets(line, 256, fp)
}

buffer =(char*)malloc(sizeof(char) * strlen(line));
strcpy(buffer, line);

基本上我不想遍历文件n-1次才能到达第n行...这似乎不是很高效(而且,这是作业,我需要得到100%哈哈)。任何帮助都将不胜感激。

如果你的行可以是任意长度,你如何期望在常数时间内跳过 n 行? - Kerrek SB
唯一真正的替代方案是建立每行起始位置的索引(读取文件一次,建立索引,然后使用它直接定位到一行,直到/除非文件发生更改)。还要注意,您的malloc需要添加1来留出NUL终止符的空间。 - Jerry Coffin
一些存储文本文件的机制可能会提供一种以常数时间或至少比线性时间更好的方式来访问第N行。可能VMS上使用的某些文件格式就是这样做的。但是C标准库没有公开任何这样的机制,在大多数操作系统上,除非你自己建立索引,否则对于纯文本文件甚至不可能实现。因此,这不是一个不合理的问题——但答案是否定的。 - Keith Thompson
5个回答

10

除非你对文件有更多的了解,否则无法随机访问特定行。新行由行结束字符分隔,并且通常可以出现在任何位置。文本文件没有允许您跳转到第n行的映射索引

如果你知道,比如说,文件中每一行都是相同的长度,则你可以使用随机访问来跳到特定的行。如果没有这种额外的信息,你唯一的选择就是迭代整个文件,直到达到所需的行。


9
如果你知道每行的长度,你可以使用fseek跳转到想要的行。
否则,你需要遍历所有的行。

5

首先,你的线路

buffer =(char*)malloc(sizeof(char) * strlen(line));

最好的写法是:

buffer = malloc(strlen(line) + 1);
+ 1是为了提供终止符'\0'的空间;strlen()没有考虑到这一点。在C语言中不需要将malloc()的结果转换成其他类型,有时候这样做只会掩盖错误。由于sizeof(char)已经被定义为1,所以这一部分也是不必要的。
并且您从未更改targetline的值,因此您的循环永远不会终止。
但是回答您的问题,如果您有一个文本文件,并且想要读取其中的第N行,您必须读取并跳过前面的N-1行才能找到它。(可以设置单独的索引,但是创建索引需要读取整个文件,并且随着文件的更改保持索引当前状态是一个困难的问题,可能超出您现在所做的范围。而且这并不是特别必要的;从文件中读取10行的时间将不会被注意到。)

3

很抱歉,获取文件中的第n行没有其他方法。您必须逐行遍历。文件内部没有随机访问。


2

如果您想从文本文件中获取第n行,您必须先读取前面的n-1行。这是一个连续文件的特性。除非您知道所有行的长度相同,否则无法可靠地定位到特定行的开头。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接