在C中返回一个2D字符数组

时间:2022-02-20 01:16:04

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.

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

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

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

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

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

6 个解决方案

#1


6  

C will not return an array from a function.

C不会从函数中返回数组。

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中打包数组并返回它。C会从函数中返回结构体。缺点是这可能是大量的内存复制

    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.)

    可以返回指向数组的指针。这个指针必须指向使用malloc(3)为数组分配的内存。(或者另一个不从堆栈中分配内存的内存分配原语。)

    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] */
    }
    

#2


5  

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 */
}

#3


1  

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.

对于编译,我使用gcc和C99选项。

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.

我将函数定义为包含两个大小的信息,但我编写了非常基本的代码,实际上根本没有使用这些信息,只是使用了strcpy(),因此无论如何,这肯定不是安全安全的代码(尽管我为这些功能显示了“m”和“n”)。它仅仅展示了一种技术,用于创建一个静态的2D char数组,并通过指向数组“字符串”的指针数组的中间部分在函数中处理它。

#4


0  

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

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

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

#5


0  

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.

因为你传递的是指针而不是值你想要写入输入数组,你必须复制它。

#6


0  

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.

下面将执行您想要的操作。它将打印“1”和“10”。还要注意,它是按照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] )
}

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

#1


6  

C will not return an array from a function.

C不会从函数中返回数组。

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中打包数组并返回它。C会从函数中返回结构体。缺点是这可能是大量的内存复制

    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.)

    可以返回指向数组的指针。这个指针必须指向使用malloc(3)为数组分配的内存。(或者另一个不从堆栈中分配内存的内存分配原语。)

    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] */
    }
    

#2


5  

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 */
}

#3


1  

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.

对于编译,我使用gcc和C99选项。

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.

我将函数定义为包含两个大小的信息,但我编写了非常基本的代码,实际上根本没有使用这些信息,只是使用了strcpy(),因此无论如何,这肯定不是安全安全的代码(尽管我为这些功能显示了“m”和“n”)。它仅仅展示了一种技术,用于创建一个静态的2D char数组,并通过指向数组“字符串”的指针数组的中间部分在函数中处理它。

#4


0  

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

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

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

#5


0  

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.

因为你传递的是指针而不是值你想要写入输入数组,你必须复制它。

#6


0  

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.

下面将执行您想要的操作。它将打印“1”和“10”。还要注意,它是按照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] )
}

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