在C语言中返回一个字符串数组并将其赋值给一个变量

3

我面临的问题如下:

在一个组件上,我读取文件名并将它们存储在一个数组中。最多可以有100个名称,每个名称最长为20个字符。定义如下:

static Char_t fileList[100][20] = {};

where

fileList[1]= "name1" 
fileList[2]= "name2"  and so on.

我想创建一个返回指向它的指针函数,以便从代码的另一个组件中访问这个字符串数组:
Char_t** getAllFiles(void)
{
    return &fileList;
}

我会像这样赋值指针:

Char_t **fileList = getAllFiles();

这似乎不起作用。我所能做到的最好的是获取数组的第一个组件的指针,但我无法获得其余的组件。


你是如何尝试通过调用者中的 fileList 访问其他组件的? - RobertS supports Monica Cellio
这就是问题所在。当我尝试调试时,我不知道如何告诉程序去到第二个、第三个...组件。如果我用 Char_t *fileList = getAllFiles(); 然后返回 fileList,那么我只会得到第一个组件的地址。 - Asan
1
你所需要的只是第一个组件的地址。矩阵在内存中是连续的,因此要访问第i行,你需要使用“p+columnSize*i”。 - Enosh Cohen
2个回答

2

一个简单的选择是使用数组指针作为返回类型。

以下是一个可重现的示例:

#include <stdio.h>

char (*getAllFiles())[];

int main(void)
{
    char (*str_array)[20] = getAllFiles();
    printf("%s %s", str_array[0], str_array[1]); //test print
}

char (*getAllFiles())[]
{
    static char fileList[100][20] = {"name1", "name2"};
    return fileList;
}

如果您不想或不需要使用静态存储,您可以使用相同类型但带有内存分配的方法,这将允许您在不再需要数组时释放为其保留的内存。请注意,使用静态存储可能会有其缺点,正如@RobertS supports Monica Cellio pointed out

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

char (*getAllFiles())[];

int main(void)
{
    char (*str_array)[20] = getAllFiles();
    printf("%s %s", str_array[0], str_array[1]); //test print
    free(str_array); //free the allocated memory after it's used
}

char (*getAllFiles())[]
{
    //allocating space for an array of type char, which is always 1 byte, 
    //you must allocate memory according to the array type
    //for instance malloc(sizeof(Char_t) * 100 * 20);
    char (*fileList)[20] = malloc(100 * 20);

    strcpy(fileList[0], "name1");
    strcpy(fileList[1], "name2");

    return fileList;
}

两种情况下的输出:

name1 name2

1
有趣。我以前不知道这个方法。但我认为我们互相学到了东西,这很棒。 - RobertS supports Monica Cellio
1
一个小提示:malloc(100 * 20) 很聪明,但是如果 fileList 的类型改变了呢 - 这是一个不容忽视的情况 - 而且请记住 OP 可能会在其他类型不同的情况下使用这种技术。malloc(sizeof(char) * (100 * 20)) 更清晰易读,我想更安全。另外请注意,OP 正在使用神秘的 Char_t,它可能与 char 在大小上不等价 -> sizeof(char) != sizeof(Char_t) - RobertS supports Monica Cellio
@RobertS支持MonicaCellio,是的,我想我也应该在那里留下评论。 - anastaciu
@RobertSsupportsMonicaCellio,只是有点挑剔:)内存分配也有其缺点,它非常昂贵,静态分配要快得多。 - anastaciu
1
是的,我想我们只能选择优化的方式,但并不意味着它是最优化的。 :-) - RobertS supports Monica Cellio
@RobertS支持MonicaCellio的确。 - anastaciu

1

可能更好的方法是动态分配数组,因为在不再需要该数组之后,您可以取消分配该数组。

从函数外部指向函数本地对象也被认为是“不良实践”,因为它不是线程安全的。

详细来说,首先分配一个指向Char_t的20个指针的数组,并将其赋值给**fileList。然后为每个指针分配100个Char_t的内存。

返回fileList并将其分配给调用者中的指向指针Char_t的指针。

之后,您只需使用file_list[i]即可访问特定的字符串。

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

char** getAllFiles (void);

typedef char Char_t;

int main (void)
{
    Char_t** file_list = getAllFiles();

    printf("%s\n", file_list[0]);
    printf("%s", file_list[1]); 

    for (int i = 0; i < 20; i++)
    {
        free(file_list[i]);     // deallocate pseudo-rows of 100 Char_t.
    }

    free(file_list);            // deallocate pointer array.

}

char** getAllFiles (void)
{
    Char_t** fileList = malloc (sizeof (*fileList) * 20);

    for (int i; i < 20; i++)
    {
        fileList[i] = malloc (sizeof (**fileList) * 100);
    }

    strcpy(fileList[0], "name1");
    strcpy(fileList[1], "name2");

    return fileList;
}

输出:

name1
name2

将一个具有静态存储的变量返回并不是一种坏的做法,至少就我所知。https://dev59.com/Vovda4cB1Zd3GeqPbJNk#30621826 - anastaciu
@anastaciu 在关于这个评论中讨论了为什么返回指向静态函数局部对象的指针可能不是最好的选择。 - RobertS supports Monica Cellio
1
如果您真的想要分配内存,您也可以为指向数组类型的 (*arr)[] 指针执行操作,这是更简单的代码,只需要一次分配和释放,我唯一能看到的优点是您可以释放内存,而静态变量的生命周期与程序相同。它们都存在于堆中。 - anastaciu
我能看到缺点,OP已经在使用它了,指出使用它的缺点肯定很重要,但我不会说这是一个不好的做法,我尊重这个观点,每个人都有权拥有自己的观点。 - anastaciu

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