Deathkamp Drone
Deathkamp Drone

Reputation: 282

How can I read a specific line from a file, in C?

All right: So I have a file, and I must do things with it. Oversimplifying, the file has this format:

n
first name
second name
...
nth name
random name
do x⁽¹⁾, y⁽¹⁾ and z⁽¹⁾
random name
do x⁽²⁾, y⁽²⁾, z⁽²⁾
...
random name
do x⁽ⁿ⁾, y⁽ⁿ⁾, z⁽ⁿ⁾

So, the actual details are not important. The problem is: I'll have to declare a variable n, I have an array name[MAX], and I'll fill this array with the names, from name[0] to name[n-1].

Alright, the problem is: How can I get this input, if I don't know previously how many names do I have?

For example, I could do it just fine if that was an user input, from the keyboard: I would do it like this:

int n; char name[MAX];
scanf( "%d", &n);
int i; for (i = 0; i < n; i++)
    scanf( "%s", &N[i]);

And I could go on, do the whole code, but you get the point. But, my input now comes from a file. I don't know how can I get the input, all I can do is to fscanf() the whole file, but since I don't know its size (the first number will determine it), I can't do it. As far as I know (please correct me if that's not true, I am very new to this), we can't use the command "for" and get the numbers gradually as if that was coming from the keyboard, right?

So, the only exit I see is to find a way to read a particular line from the file. If I can do this, the rest is easy. The thing is, how can I do that? I google'd it, I even found some questions in there, though it didn't make any sense at all. Apparently, reading a particular line from a file is really complicated.

This is from a beginner problem set, so I doubt it is something that complicated. I must be missing something very simple, though I just don't know what it is.

So, the question is: How would you do it, for instance?

How to scan the first number n from the file, and then, scan the others 'n' names, assigning each one to an element in an array (first name = name[0], last name = name[n - 1])?

Upvotes: 2

Views: 3353

Answers (3)

bibz
bibz

Reputation: 11

I would suggest looking into End Of File.

while(!eof(fd))
{
...code...
}

Mind you my C knowledge is rusty, but this should get you started.

IIRC eof returns a value (-1) so that's why you need to compare it to something. Here fd being file descriptor of the file you are reading. Then after parse of text or count of lines you have your 'n'.

EDIT: Since I'm obviously more tired then I thought(didn't notice your 'n' at the top).
Read first line malloc for 'n' size array for loop to iterate names.

Upvotes: 1

Gilbert
Gilbert

Reputation: 3776

Here you go.. I leve compiling and debugging as an exercise for the student.

The idea is to slurp the whole file into a single array if you files are always small. This is so much more efficient than scanf().

char buf[100000], *bp, *N[1000];   // plenty big

memset( buf, '\0', sizeof buf );
if ( fgets( buf, sizeof(buf), fd ) )
{
    int   n  = 0;
    char *bp;
    if ( buf[(sizeof buf)-2)] != '\0' )
    {   // file too long for buffer
        printf( stderr, "trouble: file too large: %d\n", (int)(sizeof buf));
        exit(EXIT_FAILURE);
    }
    // now replace each \n with a \0, remembering where each line is.
    for ( bp = buf, bp = strchr( bp, '\n' ); bp++ )
        N[n++] = bp;
}

If you want to read any size files you need to read the file in chunks, calloc()ing each chunk before a read, and carefully handling of the line fragments left at the end of the current buffer to move them to the next buffer and then properly continuing you reads. Unless you have a limit on how many lines you can read the N may need to also be set up in chunks, but this time remalloc() might be your friend.

Upvotes: 0

Mark Wilkins
Mark Wilkins

Reputation: 41232

Since the given format seems to imply that the number of names n is given as the first entry in the file, it would be possible to use the style of reading that the OP describes when reading from stdin. Use fscanf to read the first integer from the file (n), then use malloc to allocate the array(s) for the names, then use a for loop up to n to read the names.

However, I am unsure of the meaning of the example data following that with the do x⁽¹⁾, y⁽¹⁾ and z⁽¹⁾ format. Perhaps I am not understanding part of the question. If it means there are potentially more than n names, then you can use realloc to grow the size of the array. One way of growing the array that is not uncommon is to double the length each time.

Upvotes: 0

Related Questions