循环内的结构数组

Nic*_*ico 1 c arrays struct loops

我正在学习C,我正在玩结构,但我发现了一些我无法解释的行为,我想知道它为什么会发生.

这是我的代码:

struct my_struct{
  char *name;
};

int main()
{

  struct my_struct arr[3];
  int i = 0;
  char str[10];

  while (i<3)
  {
    fgets(str, 10, stdin);
    arr[i].name = str;
    printf("Array number %d: %s", i, arr[i].name); 
    i++;
  }

  printf("1 - %s\n2 - %s\n3 - %s", arr[0].name, arr[1].name, arr[2].name);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的意见:

test1
test2
test3
Run Code Online (Sandbox Code Playgroud)

预期产量:

Array number 0: test1

Array number 1: test2

Array number 2: test3
1 - test1

2 - test2

3 - test3
Run Code Online (Sandbox Code Playgroud)

结果输出:

Array number 0: test1

Array number 1: test2

Array number 2: test3
1 - test3

2 - test3

3 - test3
Run Code Online (Sandbox Code Playgroud)

结果输出:

问题是,只要while循环继续运行,它似乎没问题; 但是,当它退出时,它似乎将数组中结构的每个"名称"值设置为最后一个.

如果,一旦离开循环并在最后一个printf()之前,我手动设置数组中最后一个结构的名称,这是唯一一个更新的结构,但前面的结构名称仍然设置为最后一个进入循环内部.

我想我错过了关于内存管理的事情,比如在再次调用fgets()之前刷新缓冲区,或者无法弄清楚发生了什么.有谁知道这是关于什么的?

Fan*_*Fox 5

这就是你所期望的,你可以这样思考char str[10],这是你的字符串存储的内存.当您设置每个数组名称时,arr[i].name = str您指向char * name此内存.所以这是你的for循环正在做的事情:

0. str = [];         arr[0].name = NULL; arr[1].name = NULL; arr[1].name = NULL;
1. str = [string1];  arr[0].name = str;  arr[1].name = NULL; arr[1].name = NULL;
2. str = [string2];  arr[0].name = str;  arr[1].name = str;  arr[1].name = NULL;
3. str = [string3];  arr[0].name = str;  arr[1].name = str;  arr[1].name = str;
Run Code Online (Sandbox Code Playgroud)

因此,在循环结束时,所有arr.name指针都指向字符串,并且每次都编辑了字符串.如果您希望单个arr元素存储自己的字符串,那么最好这样做:

struct my_struct{
  char name[10]; // Note how each instance of `my_struct` now stores its own string.
};

int main() {
  struct my_struct arr[3];
  int i = 0;

  while (i<3) {
    fgets(arr[i].name, 10, stdin);
    printf("Array number %d: %s", i, arr[i].name); 
    i++;
  }

  printf("1 - %s\n2 - %s\n3 - %s", arr[0].name, arr[1].name, arr[2].name);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

实例

作为最后一点,你应该避免使用fgets (见这里).更喜欢getline.