0

So say I am reading a 2d array from a textfile, and I don't happen to know what the dimensions will be, thus leading me to using malloc. That being said, here is my failed attempt hopefully you guys can follow through and guide me because I'd LOVE to know how to do this!

void 2dArray(double **arr, int N, int M) {
  int i,j;
  FILE *fp; 
  fp = fopen("array.txt", "r"); 
  for(i=0; i < N; i++) {
    for(j=0; j < M; j++) {
         fscanf(fp, "%lf", &arr[i][j]);
    }
  }
}

int main() {
  int **array;
    // How do I initialize this??
    // heres my attempt:
  array = (double **)malloc(sizeof(double*);
  2dArray(array, N, M);
    //Where would I get N and M?
borat
  • 13
  • 2
  • Can you clarify the problem? Suppose your text file contains 12 numbers. How would you then figure out that the 2D array contains, say, 3×4 elements, and not 4×3 (or 6×2, or 12×1, etc.)? It might help if you included an example of a text file in your question. – r3mainer Dec 05 '16 at 10:39

1 Answers1

1

First you should allocate resources with known data. In order to know the data you should open the file and count your 2d array's dimensions. It should look like this:

int **array;
int *n, *m,i;
n = malloc(sizeof(int));
m = malloc(sizeof(int));
findArraySize(n,m); //will find and write array size to n and m

//start of bad allocation method with lots of seperate resource in actual memory
array = malloc(n*sizeof(double*)); //allocate resource for pointer to pointer
for(i = 0 ; i < n ; i++)  //allocate resource for each pointer
    array[i] = malloc(m*sizeof(double));
//end of bad allocation method

//or you can use the allocation method below for better performance and readability 
//(*array)[m] = malloc ( sizeof(double[n][m]) );

2dArray(array, *n, *m);

and your findArraySize function should be something like this:

void findArraySize(int* n, int *m){
    int i,j;
    FILE *fp; 
    char separators[] = " ";
    char line[256];
    char * p;
    *n = 0;
    *m = 0;

    fp = fopen("array.txt", "r"); 

    while(!eof(fp)){
        fgets(line, sizeof(line), fp);
        p = strtok(line, separators);
        *n += 1;
        *m = 0; //we assume array is well defined, m is same for each row
        while (p != NULL) {
            *m += 1;
            p = strtok(NULL, separators);
        }
    }
}
cokceken
  • 2,068
  • 11
  • 22
  • 1
    There is no reason at all to use pointer-to-pointer here. Just allocate a 2D array instead. `int (*array)[m] = malloc ( sizeof(int[n][m]) );`. There is also no reason to allocate `n` and `m` dynamically, all you achieve with that is a slower program. – Lundin Dec 05 '16 at 11:35
  • You are right but i think allocating all pointers separately explains the logic behind better. – cokceken Dec 05 '16 at 11:42
  • 1
    Allocating each segment separately creates a look-up table pointing at segments. Apart from it being needlessly complex and notoriously error-prone, it effectively blocks the use of data cache, turning your program needlessly slow. – Lundin Dec 05 '16 at 11:57
  • You are right i am going to edit my comment with both possible ways – cokceken Dec 05 '16 at 12:01
  • see [Why is “while ( !feof (file) )” always wrong?](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – BLUEPIXY Dec 05 '16 at 15:24