在C中创建2(或3?)维字符串数组

标签 c multidimensional-array dynamic-memory-allocation c-strings variable-length-array

我想创建一个字符串数组,例如:

{{"zero","zero"},
{"zero","one"},
{"one","zero"},
{"one","one"}}

如果我没记错的话我需要 3D 数组。如何使用动态内存分配创建它以及如何从函数返回它?我的意思是我的函数应该如何(char ***getString 等...),在我的主函数中,我该如何使用它? char ***string = getstring(); 有效吗?

我还不知道我必须使用 3d 数组,我尝试使用 2 个 malloc。 我在函数中创建数组字符串,如

char** editKeys = malloc(128 * sizeof(char*));
for (int i = 0; i < 128; i++ )
{
    editKeys[i] = (char*) calloc(2, sizeof(char));
}

并且它可以正常工作。之后我从 main 中调用了我的函数,例如

char **editFile=getEditFile();
printf("%s",editFile[0][0]);

此时我失败了,现在我不能确定它是 2d 还是 3d,我的大脑也失败了。无法想象如何将其转换为 3d 数组。

最佳答案

如果您的编译器支持可变长度数组,那么您可以按以下方式分配数组

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

void f( size_t n1, size_t n2, size_t n3, char s[n1][n2][n3] )
{
    for ( size_t i = 0; i < n1; i++ )
    {
        if ( i < n1 / 2 )
        {
            strcpy( s[i][0], "zero" );
        }
        else
        {
            strcpy( s[i][0], "one" );
        }

        if ( i % 2 == 0 )
        {
            strcpy( s[i][1], "zero" );
        }
        else
        {
            strcpy( s[i][1], "one" );
        }
    }
}

int main(void) 
{
    enum { N1 = 4, N2 = 2, N3 = 5 };
    char ( *p )[N2][N3] = malloc( sizeof( char[N1][N2][N3] ) );

    f( N1, N2, N3, p );

    for ( size_t i = 0; i < N1; i++ )
    {
        printf( "\"%s\" \"%s\"\n", p[i][0], p[i][1] );
    }

    free( p );

    return 0;
}

程序输出为

"zero" "zero"
"zero" "one"
"one" "zero"
"one" "one"

或者您确实可以分配数组的数组的数组。

例如

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

void f( char ***s, size_t n1, size_t n2, size_t n3 )
{
    for ( size_t i = 0; i < n1; i++ )
    {
        if ( i < n1 / 2 )
        {
            strcpy( s[i][0], "zero" );
        }
        else
        {
            strcpy( s[i][0], "one" );
        }

        if ( i % 2 == 0 )
        {
            strcpy( s[i][1], "zero" );
        }
        else
        {
            strcpy( s[i][1], "one" );
        }
    }
}

int main(void) 
{
    enum { N1 = 4, N2 = 2, N3 = 5 };
    char ***p  = malloc( N1 * sizeof( char ** ) );

    for ( size_t i = 0; i < N1; i++ )
    {
        p[i] = malloc( N2 * sizeof( char * ) );
        for ( size_t j = 0; j < N2; j++ )
        {
            p[i][j] = malloc( N3 );
        }
    }

    f( p, N1, N2, N3 );

    for ( size_t i = 0; i < N1; i++ )
    {
        printf( "\"%s\" \"%s\"\n", p[i][0], p[i][1] );
    }


    for ( size_t i = 0; i < N1; i++ )
    {
        for ( size_t j = 0; j < N2; j++ )
        {
            free( p[i][j] );
        }

        free( p[i] );
    }

    free( p );

    return 0;
}

获得程序输出为

"zero" "zero"
"zero" "one"
"one" "zero"
"one" "one"

还有第三种方法,其中指针的数量可以少于最后一种情况。您所需要的只是分配一个指向二维数组第一个元素的一维指针数组。

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

enum { N1 = 4, N2 = 2, N3 = 5 };

void f( char ( **s )[N3], size_t n1 )
{
    for ( size_t i = 0; i < n1; i++ )
    {
        if ( i < n1 / 2 )
        {
            strcpy( s[i][0], "zero" );
        }
        else
        {
            strcpy( s[i][0], "one" );
        }

        if ( i % 2 == 0 )
        {
            strcpy( s[i][1], "zero" );
        }
        else
        {
            strcpy( s[i][1], "one" );
        }
    }
}

int main(void) 
{
    char ( **p )[N3]  = malloc( N1 * sizeof( char ( * )[N3] ) );

    for ( size_t i = 0; i < N1; i++ )
    {
        p[i] = malloc( N2 * sizeof( char[N3] ) );
    }

    f( p, N1 );

    for ( size_t i = 0; i < N1; i++ )
    {
        printf( "\"%s\" \"%s\"\n", p[i][0], p[i][1] );
    }


    for ( size_t i = 0; i < N1; i++ )
    {
        free( p[i] );
    }

    free( p );

    return 0;
}

最后(我希望)有第四种方法来首先声明一个指向数组的指针数组。

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

enum { N1 = 4, N2 = 2, N3 = 5 };

void f( char * ( *s )[N2], size_t n1, size_t n3 )
{
    for ( size_t i = 0; i < n1; i++ )
    {
        if ( i < n1 / 2 )
        {
            strcpy( s[i][0], "zero" );
        }
        else
        {
            strcpy( s[i][0], "one" );
        }

        if ( i % 2 == 0 )
        {
            strcpy( s[i][1], "zero" );
        }
        else
        {
            strcpy( s[i][1], "one" );
        }
    }
}

int main(void) 
{
    char * ( *p )[N2]  = malloc( N1 * sizeof( char * [N2] ) );

    for ( size_t i = 0; i < N1; i++ )
    {
        for ( size_t j = 0; j < N2; j++ )
        {
            p[i][j] = malloc( N3 * sizeof( char ) );
        }           
    }

    f( p, N1, N3 );

    for ( size_t i = 0; i < N1; i++ )
    {
        printf( "\"%s\" \"%s\"\n", p[i][0], p[i][1] );
    }


    for ( size_t i = 0; i < N1; i++ )
    {
        for ( size_t j = 0; j < N2; j++ ) free( p[i][j] );
    }

    free( p );

    return 0;
}

如果编译器确实支持变长数组,那么第一种方法是最好的。

注意:在这些方法中,有时不使用某些参数,例如n2,因为我知道它等于2。但一般情况下应该指定。

关于在C中创建2(或3?)维字符串数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57909034/

相关文章:

python-3.x - 我可以使用 reshape +转置技巧来创建重叠的平铺吗?

c++ - 获取和设置二维数组对象值 (C++)

c++ - 链表在递归搜索列表中不存在的元素时会核心转储

c - XINU OS - 理解 roundmb 函数

android - 如何使用 ARM NEON 优化循环 4D 矩阵 vector 乘法?

c - 尝试反转数组中的多个整数 - 想知道为什么我的代码不起作用

c - 访问带下标的 long long int 指针

Python 将字符串转换为固定列数组

c++ - Char* 数组内存泄漏

c++ - 内存:编译器如何选择存储变量的位置?