动态分配的 char 数组只打印每个索引的第一个字符

dynamically allocated char array only prints first character from each index

我正在尝试从一个文件中读取,该文件中的单词之间用空格分隔,这些单词是在一个循环中读取的。它们在循环中被正确读取,并且可以这样打印,但是一旦循环结束,我只能打印每个元素的第一个字符。这是代码:

char **storeWords(char **words){

    char* fileName = "words.txt";
    FILE* fp = fopen(fileName, "r");
    int i;
    for (i = 0; i < 2; i++){
        int j;
        for (j = 0; j < 20; j++){
            fscanf(fp, "%s", &words[i][j]);
            printf("%s", &words[i][j]); //prints correctly
        }
    }
    printf("%s", &words[0][0]); //prints first character of selected element
    fclose(fp);
    return **words;
}

int main(){
    char **words = (char**)malloc(6 * sizeof(char*));
    for (int i = 0; i < 6; i++){
        words[i] = (char*)malloc(20 * sizeof(char));
    }

   storeWords(words);

   system("pause");
   return 0;
}

我不明白为什么会这样,如果能解释一下,我们将不胜感激。谢谢。

问题是您分配的是二维字符数组,而不是二维字符串数组。

这是一个指向字符串或一维字符数组的指针:

char*

这是一个指向一维字符串数组或二维字符数组的指针:

char**

这是一个指向 2D 字符串数组或 3D 字符数组的指针:

char***

您试图将一个字符串存储到一个字符中,您没有崩溃的唯一原因是您分配了一个 [6][20] 数组,但只迭代了 2x20 个单词,所以有空间溢出。

所以,在你的 main 函数中你需要像这样分配(注意你不需要转换从 malloc 返回的指针):

char ***words = malloc(6 * sizeof(char**));
for (int i = 0; i < 6; i++){
    words[i] = malloc(20 * sizeof(char*));        
}

更改您的函数声明以使用新类型:

char ***storeWords(char ***words)

然后当你读入单词时,使用临时字符缓冲区并根据单词大小动态分配足够的space:

for (j = 0; j < 20; j++){
    char word[100]; // max word size of 100 chars
    fscanf(fp, "%99s", word);
    words[i][j] = malloc(strlen(word) + 1);
    strcpy(words[i][j], word);
    printf("%s", words[i][j]); //prints correctly
}

请注意,当您打印出一个单词时,您不需要使用 & 符号,因为 words[i][j] 现在包含一个 char* 而不是一个 char:

printf("%s", words[0][0]);