如何在C语言中返回字符串数组?

7
例如,我在主文件中有以下内容:
1) char ** array[NUMBER];
2) array = build_array();

并且在一个导入的文件中

char ** build_array()
{
  char ** array[NUMBER];
  strings[0] = "A";
  strings[1] = "B";
  return (char *) strings;
}

然而,在主文件的第2行,我遇到了错误:"incompatible types when assigning to type 'char **[(unsighed int)NUMBER]' from type 'char **'

我做错了什么?如果有任何建议或意见,请不吝赐教。谢谢。

4
发布实际代码?strings在哪里定义?为什么要获取字面字符串的指针?等等... - K-ballo
1
“array” 应该是 “strings” 吗?你试图返回一个指向栈分配对象的指针吗? - K-ballo
我只想调用build_array()函数并返回字符串数组(指向字符数组的指针),以便在主函数中使用。 - user748176
字符串并不是字符数组的指针,它们只是指向字符的指针。 - K-ballo
好的,我错了。我应该怎么做? - user748176
我应该返回指向指针数组的指针吗?我该如何实现这个? - user748176
3个回答

16

在C语言中,关于什么是字符串存在一些混淆。在C语言中,以空字符结尾的char序列被认为是一个字符串。它通常由char*表示。

我只想调用build_array()函数并返回一个字符串数组

你基本上不能返回一个数组,也不能指向局部数组的指针。但是,你可以将数组和其大小作为参数传递给build_array,然后填充该数组。

void build_array( char* strings[], size_t size )
{
  // make sure size >= 2 here, based on your actual logic
  strings[0] = "A";
  strings[1] = "B";
}
...later called as:...
char *array[NUMBER];
build_array(array, NUMBER);

另一种选择是返回指向全局或静态分配的数组的指针,这将使您的函数不可重入。现在您可能不在意这个问题,但这是不好的做法,因此我建议您避免采用这种方法。


非常感谢。现在它已经编译了,但是当我尝试打印内容时,没有任何东西打印或者打印出乱码。分配值给数组有问题吗? - user748176
@LearningPython:我们只看到了你的代码很少的部分,我不知道。NUMBER是如何定义的?你尝试如何打印内容? - K-ballo
@LearningPython:嗯,我很感兴趣......它是什么? - K-ballo
使用 int 作为数组大小?真的吗? ;) - Chris Lutz
@Chris Lutz:如果在C++中,我会选择无符号的std::size_t,这是你的意思吗? - K-ballo
@K-ballo - size_t 在 C 中也是一种类型,它是由 sizeof 返回的值的类型。(size_t 声明在 stddef.hstdlib.h 中) - Chris Lutz

9

正如littleadv所指出的那样,你的代码存在几个问题:

  • char **char **[ ]之间不匹配。

  • 返回一个指向局部变量的指针。

  • 等等。

这个例子可能会有所帮助:

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

#define NUMBER 2
#define MAX_STRING 80

char **
build_array ()
{
  int i = 0;
  char **array = malloc (sizeof (char *) * NUMBER);
  if (!array)
    return NULL;
  for (i = 0; i < NUMBER; i++) {
    array[i] = malloc (MAX_STRING + 1);
    if (!array[i]) {
      free (array);
      return NULL;
    }
  }
  strncpy (array[0], "ABC", MAX_STRING);
  strncpy (array[1], "123", MAX_STRING);
  return array;
}

int
main (int argc, char *argv[])
{
  char **my_array = build_array ();
  if (!my_array) {
    printf ("ERROR: Unable to allocate my_array!\n");
    return 1;
  }
  else {
    printf ("my_array[0]=%s, my_array[1]=%s.\n",
      my_array[0], my_array[1]);
  }
  return 0;
}

在这个很好的例子中,“NUMBER”是预先知道的。如果这个数字在“build_array()”内部决定,我们能从调用者函数得到返回数组的长度吗? - coterobarros
1
当然,其中一种方法是将#/元素作为“输出”参数传递回调用者。例如:char ** build_array(int * nelms),然后在build_array()函数内部使用:*nelms = number; - paulsm4

1

你的返回类型是char**,而你正在将其分配给char**[],这是不兼容的。

除此之外,你应该发布你遇到问题的实际代码,你发布的代码无法编译并且没有太多意义。

为了修复你的代码,函数应该返回char **[NUMBER]。还要注意,你将返回值强制转换为char*,而不是你声明的char**(或者应该是char **[NUMBER],实际上也是)。

哦,还有,在你的情况下返回指向本地变量的指针是一个完美的崩溃和未定义行为的配方。

你可能想表达的是:

char *array[NUMBER];
int ret = build_array(array, NUMBER);
// do something with return value or ignore it

并且在一个导入的文件中

int build_array(char **arr, int size)
{
  // check that the size is large enough, and that the
  // arr pointer is not null, use the return value to
  // signal errors
  arr[0] = "A";
  arr[1] = "B";
  return 0; // asume 0 is OK, use enums or defines for that
}

返回一个字符串数组应该使用什么返回类型? - user748176

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