anony
anony

Reputation: 79

How to use pointers to return 2D arrays functions?

So I have a function called scanCode which scans words from a text file and stores it in a 2D array. I then want to return this array into an array variable in the main function, this is my code so far

#include <stdio.h>

char **scanCode()
{
    FILE *in_file;
    int i = 0;
    static char scan[9054][6];

    in_file = fopen("message.txt", "r");
    while (!feof(in_file))
    {

        fscanf(in_file, "%s", scan[i]);
        i++;
    }
    return scan;
}

int main(void)
{

    int hi[9053];

    FILE *in_file;

    in_file = fopen("message.txt", "r");

    char **array = scanCode();

    printf("%c", array[0]);
    printf("%c", array[1]);
    printf("%c", array[2]);
    printf("%c", array[3]);
}

So basically the array returned from the scanCode function I want it to be stored in the char array in the main function.. after looking at a lot of questions and answers here, this is what I got to but the pointer etc is hard to understand for me.. could someone tell me what I did wrong here?

Upvotes: 1

Views: 177

Answers (3)

gaetanoM
gaetanoM

Reputation: 42044

I prefer to simplify the code in this way:

#include <stdio.h>

#define NumLines   9054
#define NumCols    6

void freeMem(char **ele) {
    while (*ele != NULL) {
        free(*ele);
        ele++;
    }
}

char **scanCode(char *fileName)
{
    FILE *in_file;
    char readingFormat[128];
    int i = 0;

    /*
     * Instead to declare a static variable I prefer to allocate dynamically
     * the bidimensional array.
     * It is done in two steps:
     * 1. allocate the memory for the first dimension
     * 2. for each element in this dimension allocate the memory for each element in the second dimension
     *
    */
    char **scan = (char **)malloc((NumLines + 1) * sizeof(char *));
    if (scan == NULL) {
        return NULL;
    }
    for (int j = 0; j < NumLines; j++) {
        scan[j] = (char *)malloc(NumCols + 1);
        if (scan[j] == NULL) {
            freeMem(scan);
            return NULL;
        }
        scan[j][0] = NULL;
    }
    scan[NumLines] = NULL;  // define the end of memory

    in_file = fopen(fileName, "r");
    if (fopen == NULL) {
        freeMem(scan);
        return NULL;
    }
    sprintf(readingFormat, "%%%ds", NumCols);
    while (fscanf(in_file, readingFormat, scan[i]) == 1 && i < NumLines) {
        i++;
    }
    return scan;
}

int main(void)
{
    char **array = scanCode("message.txt");
    if (array == NULL) {
        printf("ERROR\n");
        exit(0);
    }
    for (char **tp = array; **tp != NULL; tp++) {
        printf("%s\n", *tp);
    }
}

Upvotes: 2

AnArrayOfFunctions
AnArrayOfFunctions

Reputation: 3744

Arrays aren't pointers (hello from me again).

This:

static char scan[9054][6];

have the most obvious type you would expect it to be - 'char [9054][6]' and not 'char **'. It's spelled as an array of 6 elements each of which is another array of 9054 chars. On the other hand the type 'char **' is spelled as 'a pointer to pointer to char' and as you can probably see now they are entirely different things.

Your code should look something like this:

#include <stdio.h>

typedef char yourArrayType[9054][6];

typedef struct { yourArrayType return_value; } letsReturnArraysType;

letsReturnArraysType scanCode()
{
    FILE *in_file;
    int i = 0;
    yourArrayType scan;

    in_file = fopen("message.txt", "r");
    while (!feof(in_file))
    {

        fscanf(in_file, "%s", scan[i]);
        i++;
    }
    return *(letsReturnArraysType*)scan;
}

int main(void)
{

    int hi[9053];

    FILE *in_file;

    in_file = fopen("message.txt", "r");

    letsReturnArraysType arrayStruct = scanCode();

    printf("%s", arrayStruct.return_value[0]);
    printf("%s", arrayStruct.return_value[1]);
    printf("%s", arrayStruct.return_value[2]);
    printf("%s", arrayStruct.return_value[3]);
}

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 310930

Change the return type of the function the following way

#include <stdio.h>

char ( *scanCode() )[6]
{
    FILE *in_file;
    int i = 0;
    static char scan[9054][6];

    in_file = fopen("message.txt", "r");
    while (!feof(in_file))
    {

        fscanf(in_file, "%s", scan[i]);
        i++;
    }
    return scan;
}

int main(void)
{

    int hi[9053];

    FILE *in_file;

    in_file = fopen("message.txt", "r");

    char ( *array )[6] = scanCode();

    printf("%s", array[0]);
    printf("%s", array[1]);
    printf("%s", array[2]);
    printf("%s", array[3]);
}

Also in the printf statements use format specifier %s

And change the loop in the function like

    while ( i < 9054 && fscanf(in_file, "%5s", scan[i]) == 1 ) ++i;

Upvotes: 4

Related Questions