【问题标题】:dynamically allocated char array only prints first character from each index动态分配的 char 数组只打印每个索引的第一个字符
【发布时间】:2015-06-20 16:17:25
【问题描述】:

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

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

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

【问题讨论】:

  • fscanf(fp, "%s", &amp;words[i][j]); 覆盖每个班次。
  • 应该改用什么? @BLUEPIXY
  • 试试for (i = 0; i &lt; 2; i++){ fscanf(fp, "%19s", words[i]); printf("%s\n", words[i]); }
  • return **words; 应该是 return words;。你的编译器没有抱怨这一行吗?

标签: c memory-management multidimensional-array


【解决方案1】:

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

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

char*

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

char**

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

char***

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

所以,在你的主函数中,你需要像这样分配(注意你不需要转换从 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
}

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

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

【讨论】:

  • 谢谢,现在可以正常使用了。但我能问一下,"%99s" 是什么,它与字节有关吗? @samgak
  • 它类似于%s,但指定读入字符串的最大字符数,不包括终止的空值。是为了避免word[100]数组溢出。
猜你喜欢
  • 2021-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
相关资源
最近更新 更多