【问题标题】:Trying to pass an array of 2D strings to a function and print it尝试将二维字符串数组传递给函数并打印它
【发布时间】:2026-02-08 10:45:01
【问题描述】:

C 新手,在传递指针时遇到问题。 我正在尝试传递这个指向字符串(char[]s)的二维指针数组。我不断收到无法使用 %s 的错误,因为在函数调用中我将参数声明为 char。但是,如果我使用 %c,我只打印 'H' 'e' 'l' 的前三个字符,然后我得到一个分段错误。

Error Code:
    format specifies type 'char *' but the argument has type 'char' [-Wformat]
                            printf("%s ", in[i][j]);
                                    ~~    ^~~~~~~~
                                    %c

建议?

void printArray(char *in[]){
int i;
int j;
for (i = 0; i < 3; i++){
    for (j = 0; j < 3; j++){
        printf("%c ", in[i][j]);
    }
}


 main(){
        char *arr1[3][3];
        arr1[0][0] ="Hello";
        arr1[0][1] = "World";
        arr1[0][2] = "Today";
        arr1[1][0] = "Is";
        arr1[1][1] = "September";
        arr1[1][2] = "28";
        arr1[2][0] = "th";
        arr1[2][1] = "2021";
        arr1[2][2] = "yay";
        char *j = arr1[0][0];
        int k; 
        int p;
        printf("Before: \n");
        printArray(&j);

重申一下,目标是发送字符串数组,然后在函数“printArray”中打印它们

对不起,如果这是一个简单的问题,对 C 来说还是很陌生

谢谢

【问题讨论】:

标签: c


【解决方案1】:

更改
printArray(char *in[])

printArray(const char * in[][3])


printArray(&amp;j)

printArray(arr1)

那么,你应该可以使用%s了。

您正在传递一个 1D 数组并希望在打印中将其用作 2D。

【讨论】:

  • 给出错误:数组的元素类型不完整 'char *[]' void printArray(char *in[][])
  • 尝试指定尺寸。
  • 在函数原型中只需要指定一个维度大小,也可以同时指定。
  • 修复错误。数组只能具有未指定的第一个维度。尝试代码时,我将所有字符串都设置为 const char *。不必如此。我已经做了。主要的是,在 C/C++ 中,您必须指定除第一个以外的所有数组维度。
【解决方案2】:

使用可变长度数组 (VLA)。正是为了这个目的,它们被添加到 C 中:

void printArray(int n, int m, char *in[n][m]){
  for (int i = 0; i < n; i++){
    for (int j = 0; j < m; j++){
        printf("%s ", in[i][j]);
    }
  }
}


int main() {
  char *arr1[3][3];
  ... initialize arr1
  printArray(3, 3, arr1);
}

编辑

如注释中所述,[n] 中的大小表达式可以省略,因为它会被编译器忽略。尽管它对于自我记录仍然有用。替代声明可以是:

void printArray(int n, int m, char *in[static n][m])

关键字static 指示编译器至少in 指向的第一个n 元素是有效的。

【讨论】:

  • 我认为 [n][m] 在函数原型上完全被忽略了,但它们可以说是自文档。
  • @Neil:n 可能会被忽略,但它不能忽略 m。在不知道m的值的情况下,编译器无法计算出in[i][j]的内存地址。
  • 我认为 OP 不需要 VLA。一个固定长度的数组可能已经足够好了。但是,我仍然赞成这个答案,因为它使功能更加灵活。请注意,并非所有符合 C11 的编译器都支持 VLA,因为它是该语言的可选功能。它只是 C99 中的强制功能,但 C11 将该功能降级为可选。
【解决方案3】:

如果你想要一个固定大小的数组,你必须相信程序员会传递它的大小,就像@tstanisl 的答案一样。那是因为在 C 中,arrays passed to functions decay to pointers。在@kalyanswaroop 的回答中,大小被信任为3,但类型检查器从未检查过(这对您可能很重要,也可能不重要。)将数组传递给函数的另一种方法是使用指针,这样静态类型检查器可以确保大小匹配。 (使用cdecl。)

void printArray(char *(*in)[3][3]) {
    size_t i, j;
    for(i = 0; i < sizeof *in / sizeof **in; i++) {
        for(j = 0; j < sizeof **in / sizeof ***in; j++) {
            printf("%s ", (*in)[i][j]);
        }
    }
}

这改变了原型;你可以称它为printArray(&amp;arr1)

【讨论】: