在C语言中返回二维数组…

3
我在C方面是个彻头彻尾的新手。我无法将这个函数与main函数联系起来。我试图打印一个二维数组,但总是出现分段错误。非常感谢您的帮助。
编辑:当我将最后一行的“printf(“%d:[%s] \ n”,i,*(p + i))”从%s更改为%c时,我得到了我正在从中读取的文件的第一个单词。所以事实证明,确实有东西从我的函数返回。现在只需要弄清楚如何让它从文件的其他行返回单词。
#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);
}

这一定是我见过的最奇怪的C代码。 - zumalifeguard
2
;} 看起来像某种表情符号。 - Ricky Mutschlechner
我在代码中加入了检查fopen()失败的部分。为了在这里只发布我关心的访问这个二维数组,我将其删除了。 - Dylan_Larkin
char s=(char)malloc(100); :内存泄漏。改为 char s[100]; - BLUEPIXY
尝试将函数返回类型(以及主函数中的p的类型)更改为char (*)[20](指向包含20个字符的数组的指针)。至于如何返回,请参见https://dev59.com/PGgv5IYBdhLWcg3wKtzj。 - Dmitri
显示剩余3条评论
3个回答

3

一般来说,你应该在main()中创建数组并将其传递进去,这种行为非常不寻常。但是,如果您坚持这样做,您必须返回指向数组的指针,因为在C中无法返回数组。

您需要类似以下的代码:

#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;
}

使用适当的输入文件,它将输出:

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$ 

请注意,这仅适用于您在read_file()中将数组声明为static的情况 - 不要以这种方式返回具有自动存储期限的局部变量指针。

如果我能在这里投上一千个赞,我会非常感谢你! - Dylan_Larkin
如果这是您正在寻找的答案,并且您倾向于接受它,那么我会满足于一个赞和一个采纳。 - Crowman

0
尝试将您的#define移回并更改函数头以返回指向size_strings个字符数组的指针,如下所示:
    #define num_strings 20
    #define size_strings 20

    char (*read_file())[size_strings] {

或者,使用typedef:

    #define num_strings 20
    #define size_strings 20

    typedef char (*PCharArr)[size_strings];

    PCharArr read_file() {

...并相应地更改主函数中p的类型:

    char (*p)[size_strings];

这将返回(指向字符数组的第一个元素的)一个字符数组的数组指针,这或多或少相当于一个char的二维数组。


-1

更新,哦我明白了,你把代码从主函数粘贴到函数中,我知道这里发生了什么,你假设p[20][20]与p*或者p**相同,那是不正确的,因为现在如果你执行*(p+1),编译器不知道p中的每个元素宽度为20而不是1。你的方法应该是在read_file中声明一个指向字符串数组的指针,并返回它:

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;

你的p应该是char*而不是int*。如果已经读取了20个项目,你还需要终止循环。


是的,我稍后会编辑格式。现在,我只想让它工作。它正在读取的txt文件很小,我分配的空间足够。我试图返回一个指向函数的指针。我把代码都写在了main()里面,它可以工作。但我的目标是能够从一个函数中调用它。 - Dylan_Larkin
我会看一下,但是代码现在已经可以工作了。感谢你的时间和努力,非常感激。 - Dylan_Larkin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接