'C function to load file contents into string array

What I'm trying to do is this:

  1. Properly initiate a 2D char array (array of strings), then,
  2. In another function, load the contents of the file to that 2D array, breaking to the next row in the 2D array at each '\n' newline character.

Since we cannot return double arrays from functions in C, I'm trying to use strncpy(), reading the file line-by-line. I've tried lots of variants, but I keep messing with the memory, so I have faced a lot of segfaults and bus errors.

Here is a model demonstrating how simple what I'm trying to do is:

int main()
{
  char *file_content[];
  load_file_to_array(file_content);
}

void load_file_to_array(char *to_load[]) {
  // something to update file_content
}

EDIT 1:

I'm not asking anyone to write my code for me. I'm frustrated with researching about this specific topic, so I decided to ask about what you guys think. Any different approach or the methodology itself are appreciated.

I have a good hunch about my approach that it is probably completely off-track.

I've looked at a lot of posts and articles about dynamic memory. The closest thing I have found to what I'm trying to accomplish is this: Changing an Array of Strings inside a function in C

EDIT 2:

As @pm100 explained in the comments, I tried:

#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 255

void load_array(char *, char *[]);

int main() {
    // NULL terminate array
    char *fn = "text.txt";
    char *arr[MAX_SIZE] = { NULL };
    // Also tried: 
    // char **arr = malloc(sizeof * char*MAX_SIZE)
    // arr[0] = malloc(sizeof(char)*MAX_SIZE);
    load_array(fn, arr);
}

void load_array(char *fn, char *fcontent[]) {
    FILE * file = fopen(fn, "r");

    char line[MAX_SIZE];
    
    int i = 0;

    // read file line by line with fgets()
    while (fgets(line, sizeof(line), file)) 
    {
        // this part I'm not sure of. maybe setting with fgets makes more
        // sense.
        strcpy(fcontent[i], line);
        i++;
        // realloc()
        fcontent = realloc(fcontent, sizeof (char*) * (i + 1));
        fcontent[i] = malloc(sizeof(char) * MAX_SIZE);
        // null terminate the last line
        *fcontent[i] = 0; 
    }

    fclose(file);
}

I get a segfault after running the program.



Solution 1:[1]

Apart from saying this is far from an efficient solution, here's yours slightly modified:

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


#define MAX_SIZE 1024
char** load_array(const char *fn) {

    char** fcontent = (char**)malloc(0);

    FILE * file = fopen(fn, "r");

    char line[MAX_SIZE];

    int i = 0;

    // read file line by line with fgets()
    while (fgets(line, sizeof(line), file))
    {
        fcontent = (char**)realloc(fcontent, (i + 1) * sizeof(char*));
        fcontent[i] = (char*)malloc(strlen(line) + 1);
        // this part I'm not sure of. maybe setting with fgets makes more sense.
        strcpy(fcontent[i], line);
        i++;
    }

    fcontent = (char**)realloc(fcontent, (i + 1) * sizeof(char*));
    fcontent[i] = NULL;

    fclose(file);
    return fcontent;
}

int main()
{
    char **lines = load_array("test.txt");
    int i = 0;
    while (lines[i])
        printf("%s", lines[i++]);

    i = 0;
    while (lines[i])
        free(lines[i++]);
    free(lines);

    return 0;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Gabriel Staples