递增指向字符串数组的指针将返回NULL

时间:2019-02-11 14:03:39

标签: c arrays string pointers

我正在尝试将字符串数组传递给要打印到屏幕的函数。第一个字符串打印正常。但是,后面的字符串为null,因此不会输出任何内容。如果我直接将指针指向第一个字符串而不是数组,则可以将其增加字符数组的大小,并且所有内容均可正确打印。如果我尝试增加指向字符串数组的指针,那是我得到null的地方。为什么会发生这种情况,以及如何正确打印阵列。同样,如果给定使用的是C标准,那么我正在使用Visual Studio,如果这完全影响到它。

我不认为错误在于调用,因为传递的指针指向字符串数组地址。

//How I'm passing the array
char headings[4][20] = { "Name", "Record Number", "Quantity", "Cost"};
int widths[4] = {20, 20, 20, 20 };
headers(&headings[0][0], &widths[0], 4);


//Function
void headers(char **heads, int *columnWidths, int noOfColumns) {
    int headLength = 0;
    printf("|");
    for (int i = 0; i < noOfColumns; i++) {
        headLength += printf("%*s|", *columnWidths, heads);
        columnWidths++;
        heads ++;
    }
    printf("\n");
    for (int i = 0; i < headLength+1; i++) {
        printf("-");
    }
    printf("\n");
}

这是我得到的输出:

|                Name|                    |                    |                       |

但是我期望得到这样的输出:

|                Name|       Record Number|            Quantity|                   Cost|

2 个答案:

答案 0 :(得分:2)

如果您有2D数组heading,则headers函数也应该接受2D数组。尽管数组在传递给函数时通常会衰减到指针,但是类型char** headschar headings[4][20]是不同的。而且您的编译器也应该警告您。

下面的代码将打印正确的输出。

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

//Function
void headers(char heads[4][20], int *columnWidths, int noOfColumns) {
    int headLength = 0;
    printf("|");
    for (int i = 0; i < noOfColumns; i++) {
        headLength += printf("%*s|", *columnWidths, *heads);
        columnWidths++;
        heads ++;
    }
    printf("\n");
    for (int i = 0; i < headLength+1; i++) {
        printf("-");
    }
    printf("\n");
}

int main(){
    char headings[4][20] = { "Name", "Record Number", "Quantity", "Cost"};
    int widths[4] = {20, 20, 20, 20};
    headers(headings, &widths[0], 4);
}

注意:您也可以将headers函数更改为接受char heads[][20],但不能更改char[][],因为那样会给您带来明显的编译器错误。

答案 1 :(得分:1)

您需要将headings传递到函数中,而不是第一个函数的第一个字符的地址。但是在C语言中,多维数组是一个完全不同的类型,并且内存布局与array of char *明显不同。

这是一个可行的变体,它支持任意维度,与公认的解决方案不同,后者仅支持数组维度4字符串,每个字符串20个字符:

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

//Function
void headers(const char **heads, int *columnWidths) {
    int headLength = 0;
    printf("|");
    while (*heads) {
        headLength += printf("%*s|", *columnWidths, *heads);
        columnWidths++;
        heads ++;
    }
    printf("\n");
    for (int i = 0; i < headLength+1; i++) {
        printf("-");
    }
    printf("\n");
}

int main(){
    const char *headings[] = { "Name", "Record Number", "Quantity", "Cost", 0};
    int widths[4] = {20, 20, 20, 20};
    headers(headings, &widths[0]);
}
  

我不认为错误在于调用,因为传递的指针指向字符串数组地址。

不。指向字符串数组的指针称为headings。这是具有两个维度的char数组。如果不了解数组的布局,就不可能遍历各个字符串。

通常,最好定义一个array of char *并使用各个字符串对其进行初始化。您可以看到数组内容的定义看起来与多维数组变体完全一样,但是内存布局却大不相同,现在可以像您最初打算的那样遍历字符串。