Tal Marziano
Tal Marziano

Reputation: 21

Passing a two-dimensional array in C function

I am trying to return a two-dimensional array from a function, but something goes wrong. arr2 on the main function is getting an error,

CXX0030: Error: expression cannot be evaluated

Code

int** file2array(char* filename) {

    FILE *fp = NULL;
    char c;
    int i = 0;
    int arr[9][9];

    if ((fp = fopen(filename, "r")) == NULL)
    {
        printf("File could not be opened\n");
    }
    else
    {
        while (!feof(fp))
        {
            c = fgetc(fp);

            if (c == '.') {
                arr[i/9][i%9] = 0;
                i++;
            }

            if (c>= '1' && c<='9') {
                arr[i/9][i%9] = c - 48;
                i++;
            }
        }
        fclose (fp);
    }

    return arr;
}

int main(){
    int** arr2 = file2array("SolverInput.txt");
}

Upvotes: 1

Views: 71

Answers (2)

Roland Illig
Roland Illig

Reputation: 41686

Arrays behave weirdly when then are passed as function parameters. That's how it is in C. Just don't do it.

Instead, you should embed the array in a struct.

typedef struct {
    int cell[9][9];
} sudoku;

You can then pass a sudoku * instead of an int ** to the function. This has the immediate benefit of telling the reader of your code what it does. An int ** can mean pretty much anything, but a sudoku * cannot.

int read_sudoku(const char *filename, sudoku *sud) {

    if (some error happens)
        return -1;

    sud->cell[3][8] = 5;
    return 0;
}

int main() {
    sudoku sud;

    if (read_sudoku("sudoku001.txt", &sud) == -1) {
        fprintf(stderr, "cannot read sudoku\n");
        return EXIT_FAILURE;
    }

    ...
}

This is the simplest it can get. No malloc, no free, just some code that does the actual work.

Upvotes: 0

David Ranieri
David Ranieri

Reputation: 41065

A 2D array int arr[9][9] and a pointer to pointer int **arr are not interchangeable, use a pointer to an array int (*arr2)[9]:

void *file2array(char* filename){
    ...
    int arr[9][9];
    ...
    return arr;
}

int (*arr2)[9] = file2array("SolverInput.txt");

But note that arr is a local variable (his lifetime ends whith the function), use malloc:

void *file2array(char* filename){
    ...
    int (*arr)[9] = malloc(sizeof *arr * 9);
    ...
    return arr;
}

int (*arr2)[9] = file2array("SolverInput.txt");
...
free(arr2);

If you don't know the number of elements before-hand (an arbitrary number instead of 9) you can use a variable-length-array (VLA)

void *file2array(char* filename, int dim){
    ...
    int (*arr)[dim] = malloc(sizeof *arr * dim);
    ...
    return arr;
}

int dim = 9;
int (*arr2)[dim] = file2array("SolverInput.txt", dim);
...
free(arr2);

Also, fgetc() returns an int (not a char)

Change

char c;

to

int c;

Upvotes: 1

Related Questions