0

I am trying to read a file into a dynamically allocated 2d array but I keep getting the same line printed out. The file I am putting into this code is a .txt with 1000 lines. The print at the end is to check if the array is getting the right data. And lastly I am trying to realloc as the code goes to fit the number of lines to put into arrays. THANKSS :)

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



int main(void)
{
    char buffer[349];
    char *del = "";
    int i = 0;
    int count = 0;
    int len = 100;
    int row = 10;
    int max = 10;
    char** d;

    d = malloc(row * sizeof(char*));

    for(i = 0; i < row; i++)
    {
        d[i] = malloc(349);
    }
    i = 0;



    while (fgets(buffer, sizeof(buffer), stdin) != NULL)
    {
        d[i] = buffer;
        i++;
        if(i == max)
        {
            d = realloc(d, sizeof(d)*2);

            for(i = max; i <= max*2; i++)
            {
                d[i] = malloc(349);
            }
            max = max * 2;
            printf("reallocating to %d\n", max);
        }

    }

    for(i = 0; i < 20; i++)
    {   
        printf("%s\n", d[i]);
        printf("%lu\n", sizeof(d[i])); 
    }
}

Sample line on txt file:

2152,1,MAIN,SOCW,6390,006,22913,IND - Independent Study,0,1,1,0,0,12:00 AM,12:00 AM,N,N,N,N,N,N,N,01-20-2015,05-08-2015

And there are about 1000 lines like these in the file.

MD XF
  • 7,860
  • 7
  • 40
  • 71
sukurity
  • 55
  • 3
  • 8

1 Answers1

0

d doesn't look like a '2D array' of anything. Arrays are contiguous. Your allocations aren't. I recommend that you change the type of d and avoid excessive allocations.

char (*d)[349] = NULL;
size_t d_size = 0;

Check if d_size is a binary power (a power of 2) to determine when to resize, and resize by doubling:

if ((d_size & (d_size + 1)) == 0) {
    void *temp = realloc(d, (2 * d_size + 1) * sizeof *d);
    if (temp == NULL) {
        perror(realloc);
        exit(EXIT_FAILURE);
    }
    d = temp;
}

Because d starts off NULL and d_size a binary power (0), the capacity check needs to go before the assignment. You can eliminate buffer as a result.

There is no need to store the capacity of d, since we know it'll be the first binary power we get to by incrementing d_size repeatedly. d_size becomes your i, if you like.


That aside, BLUEPIXY gave the solution to your problems in comments. With one correction, those were:

  1. strcpy(d[i], buffer);
  2. d = realloc(d, sizeof(*d)*max*2);
  3. for(int j = max; j < max*2; j++){ d[j] = malloc(349);}
  4. printf("%zu\n", strlen(d[i]));

At least these four are required to get your program working (whatever that means), but you should also think about these two:

  • When d = realloc(d, ...); fails and returns NULL, what happens to your previous value of d? It leaks into thin air. You should store the return value of d into a temp variable (eg. below) and check for NULL before you proceed.
  • Don't forget to free any memory you've malloc/realloc'd.

Integrating what few of those still apply into what I've learnt so far:

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

int main(void)
{
    char (*d)[349] = NULL;
    size_t d_size = 0;

    for (;;)
    {
        if ((d_size & (d_size + 1)) == 0)
        {
            void *temp = realloc(d, (2 * d_size + 1) * sizeof *d);
            if (temp == NULL)
            {
                break;
            }
            d = temp;
        }

        if (fgets(d[d_size], sizeof d[d_size], stdin) == NULL) {
            break;
        }

        d_size++;
    }

    for (size_t i = 0; i < d_size; i++)
    {   
        printf("%s\n", d[i]);
        printf("%zu\n", strlen(d[i])); 
    }

    free(d);
}
autistic
  • 1
  • 3
  • 35
  • 80