在 C 中返回二维字符数组

发布于 2024-12-16 13:56:41 字数 163 浏览 0 评论 0原文

我已经搞砸了很多次了,但我真的不明白。

这就是我想要做的:将 2D char 数组作为函数的输入,更改其中的值,然后返回另一个 2D char 数组。

就是这样。非常简单的想法,但想法在 C 中不容易实现。

任何能让我以最简单的形式开始的想法都是值得赞赏的。谢谢。

I messed around with this enough but I really don't get it.

Here is what I want to do: Take a 2D char array as an input in a function, change the values in it and then return another 2D char array.

That's it. Quite simple idea, but ideas do not get to work easily in C.

Any idea to get me started in its simplest form is appreciated. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

心的憧憬 2024-12-23 13:56:41

C 不会从函数返回数组。

您可以做几件可能足够接近的事情:

  • 您可以将数组打包在struct中,然后返回它。 C会从函数中返回struct。缺点是这可能会来回复制大量内存:

    struct arr {
        int arr[50][50];
    }
    
    结构 arr 函数(结构 arr a){
        结构 arr 结果;
        /* 对 a.arr[i][j] 进行操作
           存储到result.arr[i][j] */
        返回结果;
    }
    
  • 您可以返回一个指向数组的指针。该指针必须指向您使用 malloc(3) 为数组分配的内存。 (或者另一个不从堆栈分配内存的内存分配原语。)

    int **function(int param[][50]) {
        int arr[][50] = malloc(50 * 50 * sizeof int);
        /* 存入arr[i][j] */
        返回 arr;
    }
    
  • 您可以对传递到函数中的数组指针进行操作,并修改适当的输入数组。

    void function(int param[][50]) {
        /* 直接对 param[i][j] 进行操作——破坏输入 */
    }
    
  • 您可以使用参数作为“输出变量”并使用它来“返回”新数组。如果您希望调用者分配内存或希望指示成功或失败,这是最好的选择:

    int 输出[][50];
    
    int 函数(int param[][50], int &输出[][50]) {
        输出 = malloc(50 * 50 * sizeof int);
        /* 写入输出[i][j] */
        返回成功或失败;
    }
    

    或者,让调用者分配:

    int 输出[50][50];
    
    void 函数(int param[][50], int 输出[][50]) {
        /* 写入输出[i][j] */
    }
    

C will not return an array from a function.

You can do several things that might be close enough:

  • You can package your array in struct and return that. C will return structs from functions just fine. The downside is this can be a lot of memory copying back and forth:

    struct arr {
        int arr[50][50];
    }
    
    struct arr function(struct arr a) {
        struct arr result;
        /* operate on a.arr[i][j]
           storing into result.arr[i][j] */
        return result;
    }
    
  • You can return a pointer to your array. This pointer must point to memory you allocate with malloc(3) for the array. (Or another memory allocation primitive that doesn't allocate memory from the stack.)

    int **function(int param[][50]) {
        int arr[][50] = malloc(50 * 50 * sizeof int);
        /* store into arr[i][j] */
        return arr;
    }
    
  • You can operate on the array pointer passed into your function and modify the input array in place.

    void function(int param[][50]) {
        /* operate on param[i][j] directly -- destroys input */
    }
    
  • You can use a parameter as an "output variable" and use that to "return" the new array. This is best if you want the caller to allocate memory or if you want to indicate success or failure:

    int output[][50];
    
    int function(int param[][50], int &output[][50]) {
        output = malloc(50 * 50 * sizeof int);
        /* write into output[i][j] */
        return success_or_failure;
    }
    

    Or, for the caller to allocate:

    int output[50][50];
    
    void function(int param[][50], int output[][50]) {
        /* write into output[i][j] */
    }
    
锦爱 2024-12-23 13:56:41

您不能从函数返回数组。

您有多种选择:

  • 将数组包装在结构内
struct wraparray {
    int array[42][42];
};

struct wraparray foobar(void) {
    struct wraparray ret = {0};
    return ret;
}
  • ,将目标数组作为指向其第一个元素(及其大小)的指针传递给函数;并更改该数组
int foobar(int *dst, size_t rows, size_t cols, const int *src) {
    size_t len = rows * cols;
    while (len--) {
        *dst++ = 42 + *src++;
    }
    return 0; /* ok */
}

// example usage
int x[42][42];
int y[42][42];
foobar(x[0], 42, 42, y[0]);
  • 更改原始数组
int foobar(int *arr, size_t rows, size_t cols) {
    size_t len = rows * cols;
    while (len--) *arr++ = 0;
    return 0; /* ok */
}

You cannot return an array from a function.

You have several options:

  • wrap arrays inside structs
struct wraparray {
    int array[42][42];
};

struct wraparray foobar(void) {
    struct wraparray ret = {0};
    return ret;
}
  • pass the destination array, as a pointer to its first element (and its size), to the function; and change that array
int foobar(int *dst, size_t rows, size_t cols, const int *src) {
    size_t len = rows * cols;
    while (len--) {
        *dst++ = 42 + *src++;
    }
    return 0; /* ok */
}

// example usage
int x[42][42];
int y[42][42];
foobar(x[0], 42, 42, y[0]);
  • change the original array
int foobar(int *arr, size_t rows, size_t cols) {
    size_t len = rows * cols;
    while (len--) *arr++ = 0;
    return 0; /* ok */
}
寂寞美少年 2024-12-23 13:56:41
char **foo(const char * const * bar, size_t const *bar_len, size_t len0) {
    size_t i;        
    char** arr = malloc(sizeof(char *) * len0);
    for (i = 0; i < len0; ++i) {
        arr[i] = malloc(bar_len[i]);
        memcpy(arr[i], bar[i], bar_len[i]);
    }
    /* do something with arr */
    return arr;
}

在代码的其他地方:

char **pp;
size_t *pl;
size_t ppl;
/* Assume pp, pl are valid */
char **pq = foo(pp, pl, ppl);
/* Do something with pq */
/* ... */
/* Cleanup pq */
{
    size_t i;
    for (i = 0; i < ppl; ++i)
        free(pq[i]);
    free(pq);
} 

因为您是按指针而不是按值传递,并且想要写入输入数组,所以必须复制它。

char **foo(const char * const * bar, size_t const *bar_len, size_t len0) {
    size_t i;        
    char** arr = malloc(sizeof(char *) * len0);
    for (i = 0; i < len0; ++i) {
        arr[i] = malloc(bar_len[i]);
        memcpy(arr[i], bar[i], bar_len[i]);
    }
    /* do something with arr */
    return arr;
}

Somewhere else in your code:

char **pp;
size_t *pl;
size_t ppl;
/* Assume pp, pl are valid */
char **pq = foo(pp, pl, ppl);
/* Do something with pq */
/* ... */
/* Cleanup pq */
{
    size_t i;
    for (i = 0; i < ppl; ++i)
        free(pq[i]);
    free(pq);
} 

Because you're passing by-pointer instead of by-value and you want to write to the input array, you have to make a copy of it.

荒芜了季节 2024-12-23 13:56:41

这是另一个例子。经过测试并有效。

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

void test(char**,unsigned int,unsigned int);

const unsigned int sz_fld = 50 + 1;
const unsigned int sz_ffld = 10;

int main(void) {
    char fld[sz_ffld][sz_fld];
    for (unsigned char i=0;i<sz_ffld;++i) {
        strcpy(fld[i],"");
    }

    strcpy(fld[0],"one");
    strcpy(fld[1],"two");
    strcpy(fld[2],"three");

    char** pfld = malloc(sz_ffld*sizeof(char*));
    for (unsigned int i=0;i<sz_ffld;++i) {
        *(pfld+i) = &fld[i][0];
    }

    test(pfld,sz_ffld,sz_fld);

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

    free(pfld);

    return(0);
}

void test(char** fld,unsigned int m,unsigned int n) {
    strcpy(*(fld+0),"eleven");
    strcpy(*(fld+1),"twelve");
    return;
}

请注意以下事项:

对于编译,我使用带有 C99 选项的 gcc。

我定义了函数来包含两个大小信息,但我编写了非常基本的代码,实际上根本没有使用这些信息,只是使用了 strcpy(),所以这无论如何都不是安全的代码(即使我' m 显示此类设施的“m”和“n”)。它仅展示了一种创建静态二维字符数组的技术,并通过指向数组“字符串”的指针数组的中间部分在函数中使用它。

Here's another example. Tested and works.

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

void test(char**,unsigned int,unsigned int);

const unsigned int sz_fld = 50 + 1;
const unsigned int sz_ffld = 10;

int main(void) {
    char fld[sz_ffld][sz_fld];
    for (unsigned char i=0;i<sz_ffld;++i) {
        strcpy(fld[i],"");
    }

    strcpy(fld[0],"one");
    strcpy(fld[1],"two");
    strcpy(fld[2],"three");

    char** pfld = malloc(sz_ffld*sizeof(char*));
    for (unsigned int i=0;i<sz_ffld;++i) {
        *(pfld+i) = &fld[i][0];
    }

    test(pfld,sz_ffld,sz_fld);

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

    free(pfld);

    return(0);
}

void test(char** fld,unsigned int m,unsigned int n) {
    strcpy(*(fld+0),"eleven");
    strcpy(*(fld+1),"twelve");
    return;
}

Note the following:

For compiling, I am using gcc with the C99 option.

I defined the function to include the two sizes information, but I wrote very basic code and am not actually using the information at all, just the strcpy(), so this certainly is not security-safe code in any way (even though I'm showing the "m" and "n" for such facility). It merely shows a technique for making a static 2D char array, and working with it in a function through the intermediate of an array of pointers to the "strings" of the array.

伴梦长久 2024-12-23 13:56:41

当您将二维数组作为参数传递给函数时,您需要显式告诉它数组第二维的大小

void MyFunction(array2d[][20]) { ... }

When you pass a 2D array to a function as a parameter, you need to explicitly tell it the size of the arrays second dimension

void MyFunction(array2d[][20]) { ... }
半城柳色半声笛 2024-12-23 13:56:41

下面将做你想做的事。它将打印“一”和“十”。另请注意,它被输入为精确的数组维度 10 和 8。

char my_array[10][8] = 
{
{"One"},
{"Two"},
{"One"},
{"One"},
{"One"},
{"One"},
{"One"},
{"One"},
{"Nine"},
{"Ten"},
};

void foo ( char (**ret)[10][8] )
{
  *ret = my_array;
}

void main()
{
  char (*ret)[10][8];
  foo(&ret);

  printf("%s\r\n", (*ret)[0] )
  printf("%s\r\n", (*ret)[9] )
}

最初的问题是关于返回数组,因此我正在更新它以显示返回值。你不能直接“返回一个数组”,但你可以创建一个数组的 typedef 并返回它......

char my_array[10][8];
typedef char ReturnArray[8];
ReturnArray* foo()
{
  return my_array;
}

The following will do what you want. it will print "One" and "Ten". Also note that it is typed to the exact array dimensions of 10 and 8.

char my_array[10][8] = 
{
{"One"},
{"Two"},
{"One"},
{"One"},
{"One"},
{"One"},
{"One"},
{"One"},
{"Nine"},
{"Ten"},
};

void foo ( char (**ret)[10][8] )
{
  *ret = my_array;
}

void main()
{
  char (*ret)[10][8];
  foo(&ret);

  printf("%s\r\n", (*ret)[0] )
  printf("%s\r\n", (*ret)[9] )
}

The original question was about RETURNING the array, so I'm updating this to show returning a value. You can't "return an array" directly, but you CAN make a typedef of an array and return that...

char my_array[10][8];
typedef char ReturnArray[8];
ReturnArray* foo()
{
  return my_array;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文