【问题标题】:Creating 2 (or 3?) dimensional array of string in C在C中创建2(或3?)维字符串数组
【发布时间】:2020-01-14 11:14:41
【问题描述】:

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

{{"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 数组。

【问题讨论】:

  • 到目前为止你尝试了什么?什么不起作用?
  • 在发布您的问题之前您有没有做任何努力?如果是,请编辑您的问题,详细说明您面临的问题
  • 实际上我没有得到我必须使用 3d 数组,我用 2 个 malloc 尝试过。我在 c char** editKeys = malloc(128 * sizeof(char*)); for (int i = 0; i &lt; 128; i++ ) {editKeys[i] = (char*) calloc(2, sizeof(char)); } 这样的函数中创建数组字符串,它在函数中工作。之后我像c char **editFile=getEditFile(); printf("%s",editFile[0][0]); 这样从main 调用我的函数,此时我失败了,现在我不能确定它是2d 还是3d,我的大脑也让我失望了。想不出我怎么能把它变成 3d 数组。
  • 不要将调用结果转换为calloc() 等 - 这是不必要的,并且可以掩盖缺少原型的严重错误。

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


【解决方案1】:

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

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

Atain 程序输出是

"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。但一般情况下应该指定。

【讨论】:

    猜你喜欢
    • 2021-04-04
    • 2013-12-19
    • 2014-02-05
    • 1970-01-01
    • 2019-01-21
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多