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

时间:2015-04-14 21:31:47

标签: c memory-management multidimensional-array

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

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

我不明白为什么会发生这种情况,如果可以解释的话,我们将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:1)

问题是你正在分配一个二维的字符串数组,而不是一个二维的字符串数组。

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

char*

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

char**

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

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)

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

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
}

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

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