Returns a 2d array in C ...

I am a complete noob in C. I am unable to establish a connection between this function and main. I am trying to print a 2d array and I keep getting segmentation fault. Any help would be greatly appreciated.

EDIT: When I changed the last line 'printf ("% d: [% s] \ n", i, * (p + i))' from% s to% c, I will get the first word in the file I'm reading. It so happens that something is actually being returned from my function. Now you just need to figure out how to get it to return words from other lines in the file.

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

#define num_strings 20
#define size_strings 20

int *read_file(){
    int j = 0;
    static char text[num_strings][size_strings];

    FILE *fp;
    int x;

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

    char s[100];
    while(!feof(fp)) {
        x = fscanf(fp,"%[^\n]",s);
        fgetc(fp);

        if (x==1) {
            strcpy(text[j],s);
            j++;
        }
    }
    return text;
}

int main() {
    int *p;
    p = read_file();
    int i;
    for(i = 0; i < 10; i++) {
        printf("%d:[%s]\n",i,*(p+i));
    }
    return(0);
}

      

+3


source to share


3 answers


In general, you have to create your array in main()

and pass it, this behavior is very unorthodox. However, if you really insist on it, you should return a pointer to your array, since you cannot return arrays in C.

This is what you need:

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

#define num_strings 20
#define size_strings 20

typedef char (*PARR)[num_strings][size_strings];

PARR read_file(int * wordsread)
{
    static char text[num_strings][size_strings];
    FILE *fp;

    if ( (fp = fopen("dictionary2.txt", "r")) == NULL ) {
        fprintf(stderr, "Couldn't open file for reading\n");
        exit(EXIT_FAILURE);
    }

    char s[100];
    int j = 0;

    while ( j < num_strings && fgets(s, sizeof s, fp) ) {
        const size_t sl = strlen(s);
        if ( s[sl - 1] == '\n' ) {
            s[sl - 1] = 0;
        }

        if ( (strlen(s) + 1) > size_strings ) {
            fprintf(stderr, "String [%s] too long!\n", s);
            exit(EXIT_FAILURE);
        }

        strcpy(text[j++], s);
    }

    fclose(fp);
    *wordsread = j;
    return &text;
}

int main(void)
{
    int wordsread = 0;
    PARR p = read_file(&wordsread);

    for ( int i = 0; i < wordsread; ++i ) {
        printf("%d:[%s]\n", i, (*p)[i]);
    }

    return 0;
}

      



which, with a suitable input file, outputs:

paul@horus:~/src/sandbox$ ./twoarr
0:[these]
1:[are]
2:[some]
3:[words]
4:[and]
5:[here]
6:[are]
7:[some]
8:[more]
9:[the]
10:[total]
11:[number]
12:[of]
13:[words]
14:[in]
15:[this]
16:[file]
17:[is]
18:[twenty]
19:[s'right]
paul@horus:~/src/sandbox$ 

      

Note that this only works because you have declared your array in read_file()

as static

- do not return pointers to auto-stored local variables in this way.

+3


source


Try moving yours #define

back and change the function title to return a pointer to character arrays size_strings

like this:

    #define num_strings 20
    #define size_strings 20

    char (*read_file())[size_strings] {

      

Or alternately, with a typedef:

    #define num_strings 20
    #define size_strings 20

    typedef char (*PCharArr)[size_strings];

    PCharArr read_file() {

      



... and change the type p

in main accordingly:

    char (*p)[size_strings];

      

This will return (a pointer to the first element) an array of character arrays that is more or less equivalent to a two-dimensional array char

.

0


source


Update, oh I see you pasted the code from main into the function, I know what happened here, you assumed that p [20] [20] is the same as ap * or maybe ap **, which is not correct since now if you do * (p + 1) the compiler doesn't know that every element in p is 20 wide, not 1 wide. You should be here to declare a pointer to an array of strings in read_file and return that instead:

static char text[num_strings][size_strings];
static char *texts[num_strings]

...
while....
    ....
       if (x==1)
        {strcpy(text[j],s);texts[j]=text[j];j++;}


return texts;

      

your p must be char * not int *. You also need to end the loop if 20 items were read.

-1


source







All Articles