francescobfc
francescobfc

Reputation: 107

how to fix code that prints the code read in a file with a double char pointer

This code is intended to read the content of two files and to store them into two double char pointers, so that each element of each array stores a line of each file. When reading the files, I tell the program to print the lines, and it prints exactly as it is written. However, when I try to print random elements of the arrays of even the entire arrays themselves, outside of the foor loops, the program returns NULL or doesn't print anything.


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


int main() {

    //Opening the files
    FILE * file_1 = fopen("file1.ll", "r");
    FILE * file_2 = fopen("file2.ll", "r");
    if (file_1 == NULL || file_2 == NULL) {
        perror("Error opening file\n");
    }
    //Here I create a temporary string
    char temp_string [1000];
    // I create an array of strings
    char ** string_1 = (char **)malloc (sizeof(char * ) * 1000);
    int i = 0;
    //size_1 and size_2 will be used to account for the effective size of the arrays
    int size_1 = 0, size_2 = 0;
    //I read the file into temp_string
    while (fgets(temp_string, 1000, file_1) != NULL) {
        string_1[i] = (char *) malloc (sizeof(char) * 1000);
        //Then I copy temp_string to the element i of string_1
        strcpy (string_1[i], temp_string);
        //I print the string
        fputs(string_1[i], stdout);
        //and increase the size
        size_1++;
    }

    printf("\n\n\n\n\n\n\n\n\n\n\n");
    //I do the same for file 2
    char temp_string_2 [1000];
    char ** string_2 = (char **)malloc (sizeof(char * ) * 1000);
    while (fgets(temp_string_2, 1000, file_2) != NULL) {
        string_2[i] = (char *) malloc (sizeof(char) * 1000);
        strcpy (string_2[i], temp_string_2);
        fputs(string_2[i], stdout);
        size_2++;
    }
    //Until now everything is okay. The compiler warns nothing and the code is read and printed.
    //I've put big spaces to facilitate the reading of the code
    printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");

    //Here I try to print the first four elements of string_1, but string_1[2] and
    //string_1[3] return NULL
    printf("%s%s%s%s\n\n", string_1[0], string_1[1],string_1[2],string_1[3]);

    printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");

    //Here only two lines are printed
    for (int i=0; i<size_1; i++) {
        fputs(string_1[i], stdout);
    }
    printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
    for (int i=0; i<size_2; i++) {
        fputs(string_2[i], stdout);
    }

    system("pause");
    return 0;
}

Upvotes: 0

Views: 50

Answers (1)

user3629249
user3629249

Reputation: 16540

The following proposed code:

  1. corrects the problems identified in the comments to the OPs question
  2. properly checks for I/O and heap allocation errors
  3. properly checks that each buffer will not be overflowed by a large file
  4. avoids allocating local buffers that are not needed
  5. cleanly compiles
  6. performs the desired functionality
  7. properly cleans up after itself
  8. defines meaningful names to avoid the use of 'magic' numbers

and now, the proposed code:

#include <stdio.h>   // fopen(), perror(), FILE
#include <stdlib.h>  // exit(), EXIT_FAILURE, malloc(),  calloc()
#include <string.h>  // strcpy()

#define  MAX_LINES     1024
#define  MAX_LINE_LEN  1024


void cleanup( FILE* file1, FILE* file2, char **array1, char **array2 )
{
    if( file1 )
        fclose( file1 );

    if( file2 )
        fclose( file2 );

    if( array1 )
    {
        for( size_t i = 0; array1[i]; i++ )
            free( array1[i] );
        free( array1 );
    }

    if( array2 )
    {
        for( size_t i = 0; array2[i]; i++ )
            free( array2[i] );
        free( array2 );
    }
}


int main( void ) 
{
    FILE *file_1 = NULL;
    FILE *file_2 = NULL;
    char ** string_1 = NULL;
    char ** string_2 = NULL;

    //Opening the files
    if( !( file_1 = fopen("file1.ll", "r") ) )
    {
        perror( "fopen for file1.ll failed" );
        cleanup( file_1, file_2, string_1, string_2 );
        exit( EXIT_FAILURE );
    }

    if( !( file_2 = fopen("file2.ll", "r") ) )
    {
        perror( "fopen for file2.ll failed" );
        cleanup( file_1, file_2, string_1, string_2 );
        exit( EXIT_FAILURE );
    }

    string_1 = calloc ( sizeof(char * ), MAX_LINES );
    if( ! string_1 )
    {
        perror( "malloc failed" );
        cleanup( file_1, file_2, string_1, string_2 );

        exit( EXIT_FAILURE );
    }


    int i = 0;
    char temp_string[ MAX_LINE_LEN ];

    while ( i<MAX_LINES && fgets(temp_string, sizeof( temp_string ), file_1) )
    {
        string_1[i] = malloc ( MAX_LINE_LEN );
        if( ! string_1[i] )
        {
            perror( "malloc for new line failed" );
            cleanup( file_1, file_2, string_1, string_2 );

            exit( EXIT_FAILURE );
        }

        strcpy (string_1[i], temp_string);
        fputs(string_1[i], stdout);
    }

    printf("\n\n\n\n\n\n\n\n\n\n\n");

    //I do the same for file 2
    i = 0;  // Note: the index into the array needs to be reset

    string_2 = calloc ( sizeof(char *), MAX_LINES );
    if( ! string_2 )
    {
        perror( "malloc failed" );
        cleanup( file_1, file_2, string_1, string_2 );

        exit( EXIT_FAILURE );
    }

    while ( i<MAX_LINES && fgets(temp_string, sizeof( temp_string ), file_2) ) 
    {
        string_2[i] = malloc ( MAX_LINE_LEN );
        if( ! string_2[i] )
        {
            perror( "malloc for new line failed" );
            cleanup( file_1, file_2, string_1, string_2 );

            exit( EXIT_FAILURE );
        }

        strcpy (string_2[i], temp_string);
        fputs(string_2[i], stdout);
    }

    printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");

    printf("%s%s%s%s\n\n", string_1[0], string_1[1],string_1[2],string_1[3]);

    printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");

    //Here only two lines are printed
    for (size_t i=0; string_1[i]; i++) 
    {
        fputs(string_1[i], stdout);
    }

    printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");

    for (size_t i=0; string_2[i]; i++) 
    {
        fputs(string_2[i], stdout);
    }

    cleanup( file_1, file_2, string_1, string_2 );

    system("pause");
    return 0;
}

Upvotes: 1

Related Questions