使用fgets的意外结果


int main(int argc, char **argv)
{
    char *buf = (char *)malloc(31);
    FILE *fp = fopen("td.txt", "r");
    char* temps[4];
    for (int i = 0; i < 4; i++)
    {
        fgets(buf, 3, fp);
        temps[i] = buf;
    }
    fclose(fp);
}

我试着从这样的文本中阅读:

a
b
c
d

所以我认为temps的结果应该是:

temp[0] = 'an'
...
temp[3] = 'dn'

但实际结果是:

temp[0] = 'dn'
...
temp[3] = 'dn'

调试后,我发现每次fgets运行后,突然没有理由地改变温度。这是怎么发生的?我应该如何纠正我的代码?

buf指向一个数据内容随fgets()变化的分配。

temps[i] = buf;将指针buf赋值给temps[i]。经过4次迭代,temps[0], temps[1], temps[2], temps[3]都有相同的指针值。它们都指向与buf相同的位置。


我应该如何纠正我的代码?

为了保存用户输入的唯一副本,使用一个大的缓冲区来读取用户输入。然后为输入的副本分配合适大小的缓冲区。

#define N 4
#define BUF_SZ 100
int main(void) {
  FILE *fp = fopen("td.txt", "r");
  if (fp) {
    char buf[BUF_SZ];
    char* temps[N];
    for (int i = 0; i < N; i++) {
      if (fgets(buf, sizeof buf, fp) {
        temps[i] = strdup(buf);
      } else {
        temps[i] = NULL;   
      }
    }
    // Use temps[] somehow
    // cleanup
    for (int i = 0; i < N; i++) {
      free(temps[i]);
    }
    fclose(fp);
  }