Search code examples
cfiledynamic-memory-allocation

Read character by character from a file and put each line in a String


I've to read character by character from a file and put each line in a String. The problem is that i don't know the size of each line so eventually I've to reallocate the memory. So If I try a reallocation my program return error. Am I doing something wrong?

    FILE * file = fopen(input,"r");
    if(file != NULL){
        char temp;
        char * line;
        line =  (char *) malloc(sizeof(char) * 10);
        int i = 0;
        while((temp = fgetc(file)) != EOF){

            if(temp == '\n'){

                i = 0;
            }
            else{
                if(i > strlen(line) - 2){
                    line = (char *) realloc(line,sizeof(line) * 10);
                }
                line[i] = (char) temp;
                i++;
            }

        }
        free(line);
        fclose(file);
    }
    else{

    }



Solution

  • the following proposed code:

    1. cleanly compiles
    2. performs the desired functionality
    3. properly checks for errors
    4. outputs user error messages to stderr
    5. outputs the text reason the system thinks an error occurred to stderr
    6. documents why each header file is included
    7. shows an example of how to handle the case where the user failed to enter a command line parameter (in this case a input file name)
    8. makes use of size_t rather than int when passing parameters to malloc() and realloc()

    and now, the proposed code:

    #include <stdio.h>   // fopen(), perror(), fclose() fprintf()
    #include <stdlib.h>  // exit(), EXIT_FAILURE, malloc(), realloc(). free()
    
    
    int main( int argc, char *argv[] )
    {
        if( argc != 2 )
        {
            fprintf( stderr, "USAGE: %s <fileName>\n", argv[0] );
            exit( EXIT_FAILURE );
        }
    
    
        FILE * file = fopen( argv[1], "r" );
        if( !file )
        {
            perror( "fopen failed" );
            exit( EXIT_FAILURE );
        }
    
        // implied else, fopen successful
    
        int ch;
        char * line =  malloc( 10 );
        if( !line )
        {
            perror( "malloc failed" );
            fclose( file );   // cleanup
            exit( EXIT_FAILURE );
        }
    
        // implied else, malloc successful
    
        size_t lineLen = 10;
        size_t i = 0;
        while( (ch = fgetc(file)) != EOF )
        {
            if( ch == '\n' )
            {
                line[i] = '\0';
                // do something with contents of line
                i = 0;
            }
    
            else
            {
                if(i >= lineLen )
                {
                    lineLen *= 2;
                    char * temp = realloc( line, lineLen );
                    if( !temp )
                    {
                        perror( "realloc failed" );
                        // cleanup
                        fclose( file );
                        free( line );
                        exit( EXIT_FAILURE );
                    }
                    line = temp;
                }
                line[i] = (char)ch;
                i++;
            }
    
        }
        free(line);
        fclose(file);
    }