How to fgets() a specific line from a file in C?
Asked Answered
C

5

8

So, I'm trying to find a way to fgets() a specific line in a text file in C, to copy the contents of the line into a more permanent buffer:

Essentially, I was wondering if there was a way to do that without something similar to the following code:

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);

So basically I don't want to iterate through the file n-1 times just to get to the nth line... it just doesn't seem very efficient (and, this being homework, I need to get a 100% haha).

Any help would be appreciated.

Coenosarc answered 17/11, 2011 at 22:14 Comment(3)
If your lines can have arbitrary length, how do you expect to skip n lines in constant time?Monty
The only real alternative is to build an index of where each line starts (read the file once, build the index, then you use it to seek directly to a line until/unless the file changes). Also note that your malloc need to add 1 to leave space for the NUL terminator.Gagman
Some mechanisms for storing text files might plausibly provide a way to access the Nth line in constant time, or at least better than linear time. Probably some of the file formats used on VMS do this. But the C standard library doesn't expose any such mechanisms, and on most operating systems it's not even possible for plain text files, unless you build an index yourself. So it's not an unreasonable question -- but the answer is no.Despoil
D
10

Unless you know something more about the file, you can't access specific lines at random. New lines are delimited by the presence of line end characters and they can, in general, occur anywhere. Text files do not come with a map or index that would allow you to skip to the nth line.

If you knew that, say, every line in the file was the same length, then you could use random access to jump to a particular line. Without extra knowledge of this sort you simply have no choice but to iterate through the entire file until you reach your desired line.

Deannadeanne answered 17/11, 2011 at 22:16 Comment(0)
D
9

If you know the length of each line, you can use fseek to skip to the line you want.

Otherwise, you need to go through all lines.

Deceit answered 17/11, 2011 at 22:16 Comment(0)
D
5

First off, your line

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

is better written as:

buffer = malloc(strlen(line) + 1);

The + 1 is needed to provide room for the terminating '\0' character; strlen() doesn't account for that. Casting the result of malloc() in C is not necessary, and in some cases can mask errors. sizeof(char) is 1 by definition, so that's not needed.

And you never change the value of targetline, so your loop will never terminate.

But in answer to your question, if you have a text file and you want to read the Nth line of it, you have to read and skip the first N-1 lines to get to it. (It's possible to set up a separate index, but creating the index requires reading through the file anyway, and keeping the index current as the file changes is a difficult problem, probably beyond what you're doing now. And it's not particularly necessary; the time to read 10 lines from a file won't be noticeable.)

Despoil answered 17/11, 2011 at 22:20 Comment(0)
M
3

I'm afraid, there is no other way to get nth line in the file. You have to go through. There is no random acces within the file.

Masaryk answered 17/11, 2011 at 22:16 Comment(0)
P
2

If you want to get the nth line from a text file, you have to read the n-1 lines before it. That's the nature of a sequential file. Unless you know that all of your lines are the same length, there's no way to reliably position to the start of a particular line.

Psychomotor answered 17/11, 2011 at 22:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.