Home > OS >  C: Reading last n lines from file and printing them
C: Reading last n lines from file and printing them

Time:08-31

I'm trying to read last n lines from file and then print them. To read the lines I'm using fgets() and it seems to work fine. However, when I try to print the last n lines that I have stored in the array, it only prints the last line n times. It seems like there is something wrong with the way I store strings in an array. Here's my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int agrc, char** agrv) {
    FILE* input;
    input = fopen(agrv[1], "r");

    int n = *agrv[2]-'0';
    int line = 0;
    char text[11];
    char** tab = malloc(1000000*sizeof(text));

    while(fgets(text, sizeof(text), input) != 0) {
        tab[line] = text;
        line  ;
    }

    fclose(input);

    int jump = line-n;
    
    for(int i=jump; i<line; i  ) {
        printf("%s\n", tab[i]);
    }
}

Any help would be appreciated. Thanks in advance!

EDIT:

I've changed my while loop to this. However, it still doesn't work.

    while(fgets(text, sizeof(text), input) != 0) {
        char text2[11];
        strcpy(text2, text);
        tab[line] = text2;
        line  ;
    }

CodePudding user response:

tab[line] = text; sets tab[line] to point to the start of text. So you end up with all the tab[i] pointing to the same place, the start of text.

You need to copy each line read from the file to a different place in memory.

CodePudding user response:

It may increase your understanding if you see working code that does what you hope to achieve. Because your OP could only show 1-9 "last lines", this code doesn't try to go beyond that "meager" amount. Further, this code is meant for files whose lines "are of moderate length". It should be clear where changes can be enacted.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> // for 'isdigit()'

// Factor processing into functions for clarity
void tail( FILE *ifp, size_t n ) {
    char text[ 9 ][ 126   1   1 ]; // 9 'rows' up to 128 bytes each
    size_t lnCnt = 0;

    while( fgets( text[ lnCnt % 9 ], sizeof text[0], ifp ) != NULL )
        lnCnt  ;

    // Do the math to workout what is wanted and what's available
    if( lnCnt < n )
        n = lnCnt, lnCnt = 0;
    else
        lnCnt  = 9 - n;

    // output
    while( n-- )
        printf( "%s", text[ lnCnt   % 9 ] );

}

int main( int argc, char *argv[] ) {
    // Check parameters meet requirements
    if( argc != 3 || !isdigit( argv[ 2 ][ 0 ] ) ) {
        fprintf( stderr, "Usage: %s filename #lines (1-9)\n", argv[ 0 ] );
        exit( EXIT_FAILURE );
    }

    // Check functions didn't fail
    FILE *ifp = fopen( argv[ 1 ], "r" );
    if( ifp == NULL ) {
        fprintf( stderr, "Cannot open '%s'\n", argv[ 1 ] );
        exit( EXIT_FAILURE );
    }

    // do processing
    tail( ifp, argv[ 2 ][ 0 ] - '0' );

    // clean up
    fclose( ifp );

    return 0;
}
  • Related