0

I'm trying to store an array of string in a double pointer but it doesn't seem to be doing so.

char **pointerA;
char *pointerB;
int count;

FILE* file = fopen("textfile.ini", "r");

pointerA = (char **) malloc (sizeof(*pointerA));
pointerB = (char *) malloc (sizeof(*pointerB));

while(fgets(pointerB, 200, file) !== NULL)
{
    pointerA = (char **)realloc(pointerA, sizeof(char *) * (strlen(pointerB) + 1));
    pointerA[count] = pointerB;  
    count++;
}

fclose(file);

I expect every element to only store it's own string but it seems like all the element is storing the last string.

3 Answers3

0

pointerB = (char *) malloc (sizeof(*pointerB));

you allocate 1 char and read in the fgets up to 200.

edit

It has to be something like this

char **pointerA;
char *pointerB;

#define MAXSTRING   200

FILE* file = fopen("textfile.ini", "r");

pointerA = NULL;

size_t nlines = 0;
do
{
    pointerB = malloc(MAXSTRING);
    pointerA = realloc(pointerA, sizeof(char *) * (nlines+1));
    pointerA[nlines] = pointerB;  
    nlines++;
}while(pointerB & fgets(pointerB, , file) !== NULL)

fclose(file);
Community
  • 1
  • 1
0___________
  • 60,014
  • 4
  • 34
  • 74
0

you need to allocate each element of pointerA like so :

int nbLines = 10; //number of lines to read in file
char** pointerA = ( char** ) malloc ( sizeof ( char* ) * nbLines ); //allocate 2D array. Each element points to another string
for ( int i = 0; i < nbLines; ++i ) {
    char line [ 200 ];
    fgets ( line , 200 , file ); //get a line from the file
    pointerA [ i ] = ( char* ) malloc ( sizeof ( char ) * strlen ( line ) ); //allocate a string with the size of that line
    pointerA [ i ] = line; 

}
Midnight Exigent
  • 615
  • 4
  • 15
  • That's basically hard coding. I want something that dynamically changes when there are more lines added to the text file – ソフトウェア開発者 Nov 11 '19 at 15:10
  • you can have a function that counts the number of lines in the file : https://stackoverflow.com/questions/12733105/c-function-that-counts-lines-in-file You unfortunately can't do better in C language without keeping your code relatively simple – Midnight Exigent Nov 11 '19 at 16:58
0

If you want the program to work with n strings you could do something like this:

int cur_lines = 0;
char **pointerA = malloc(sizeof(char *) * (cur_lines + 1));
char line [200];
while(fgets(line, 200, file))
    pointerA[cur_lines] = malloc(sizeof(char) * 200); 
    strcpy(pointerA[cur_lines],line); 
    cur_lines += 1;
    pointerA = realloc(pointerA, sizeof(char *) * (cur_lines + 1));
}

Of course you should check that the results of the malloc and realloc are not NULL before using these variables, usually you don't directly overwrite the pointer you are using whith a realloc but create a new one instead and overwrite the old one if it's not NULL to avoid having memory leaks.

If you want better performance you shouldn't increase pointerA by only 1 at each loop but more than that (usually double) and keep a counter of used spaces. Also keep in mind that having a line of 200 chars means that the maximum line length is actually 199 since the last character is \0.

The problem with this approach is that you'll have one last unused malloc'd space that you need to take care of later.

John Doe
  • 1,613
  • 1
  • 17
  • 35