C:char *数组中的最后一个元素重写所有数组条目

时间:2017-11-02 18:22:24

标签: c arrays string fgets

我需要将一系列单字行从文件加载到数组中,所以我创建了一个函数来完成。该函数将char*** arr作为参数,这是一个指向字符串数组的指针。我分配内存然后有这个循环将字加载到数组中。

i=0;
FILE *fp = fopen(filename, "r");
while(fgets(tok, WORD_BUFFER, fp) != NULL){
  (*arr)[i] = tok;
  printf("Word %d:%s", i, (*dict)[i]);
  i++;
}
//arr is a char***, tok is a char[WORD_BUFFER], and WORD_BUFFER is 50

我的问题是,这似乎是用我试图进入[i]的任何东西覆盖数组的每个条目。我这样说是因为上面的循环输出的文件看起来像这样:

A
B
C
D

似乎打印正确,但是当我在主函数中打印数组时(或者甚至稍后在该函数中),它将打印出来像:

D
D
D
D

我猜这与我使用fgets(*arr)[i] = tok的分配有关,但我不确定。 谢谢!

1 个答案:

答案 0 :(得分:0)

根据您的评论,我将尝试使用简单的char*数组解释您正在做的事情。我们假设你有以下内容:

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

int main(void)
{
  int i;
  char tok[50] = "applesauce";  // tok can contain up to 49 chars plus the NUL terminator

  char* myCharPtr[20];  // this is an array 20 long where each element is of type char*

  // All the loop does is store the _address_ of tok at each position in the
  // myCharPtr array.  The _data_ "applesauce" only exists _once_ in memory,
  // and whatever that address is now fills the contents of myCharPtr.
  // (technically, "applesauce" exists twice in memory, the string literal
  // and the char array.. but neither of those places are in myCharPtr)
  for (i=0; i<20; i++)
  {
    myCharPtr[i] = tok;
  }

  for (i=0; i<20; i++)
  {
    printf("myCharPtr[%d] = %s\n", i, myCharPtr[i]);
    // prints out "applesauce" for each entry because each entry points to tok.
  }

  // Now let's do

  strcpy(tok, "apples");  // "apples" is smaller than 49, so we aren't overwriting the bounds of the array

  for (i=0; i<20; i++)
  {
    printf("myCharPtr[%d] = %s\n", i, myCharPtr[i]);
    // prints out "apples" for each entry because the _pointer_ to tok
    // hasn't changed, but the _data_ in tok has changed.
  }

  // To further re-enforce this, you can do
  printf("address of tok = %p\n", (void*)tok);
  for (i=0; i<20; i++)
  {
    printf("address of myCharPtr[%d] = %p\n", i, (void*)(&myCharPtr[i]));
  }
  // the address for tok will match all the addresses in myCharPtr

  // if you want to actually save/copy the data in tok, then you need to do
  // something like this

  char wordList[20][50];  // this can store up to 20 words that are each up
                          // to 49 chars each (must leave 1 byte for NUL termination
  for (i=0; i<20; i++)
  {
    // assume this function populates tok with new data each call, much like fgets
    // this function would have to ensure it's not writing strings bigger than 49 to tok
    GetNewContentForTok(tok);
    strcpy(wordList[i], tok);
    // now, we are saving the contents of tok each time, not simply copying
    // its pointer.
  }

  for (i=0; i<20; i++)
  {
    printf("wordList[%d] = %s\n", i, wordList[i]);
    // this will print all the strings that were once stored in tok from the previous loop
  }

  return 0;
}

我通常会尽量避免处理char***类型,因为那么多间接会让我感到困惑。我在上面的示例中使用了数组,但是相同的原则适用于指向动态分配内存的指针。