如何使用文件中的while循环为我的结构分配值?

Posted

技术标签:

【中文标题】如何使用文件中的while循环为我的结构分配值?【英文标题】:How to assign values to my structs with a while loop from a file? 【发布时间】:2021-06-28 06:42:07 【问题描述】:

我有一个包含以下数据的文件:

Mike 234234
Jack 345345
Ben 456456
Willow 567567

我有一个如下结构:

typedef struct student 
  char *name;
  char *number;
  struct student *prev;
  struct student *next;
 Student;

我正在尝试遍历文件以使用上述结构格式创建节点,然后使用名为 add 的函数将它们添加到双向链表中。

这是while循环:

FILE *in = fopen("data.txt", "r");
char name[20];
char number[20];
while (fscanf(in, "%s %s", name, number) == 2) 
  list = add(list, name, number);

但是,当我在控制台中显示链接列表时,它会显示以下内容:

[Willow - 567567]
[Willow - 567567]
[Willow - 567567]
[Willow - 567567]

而不是以下内容:

[Ben - 456456]
[Jack - 345345]
[Mike - 234234]
[Willow - 567567]

我知道指针指向内存中的相同地址,并且结构的所有实例都显示分配给这些内存地址的最终值。我的问题是,如何在内存中创建新地址并分别存储值而不是替换同一内存地址中的值?

这是我正在使用的整个代码,将其粘贴到 repl.it 将产生相同的结果。

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

typedef struct student 
  char *name;
  char *number;
  struct student *prev;
  struct student *next;
 Student;

Student* makeNode(char *name, char *number);
void print(Student *list);
Student* add(Student *list, char *name, char *number);

int main(void) 
  FILE *in = fopen("data.txt", "r");
  Student *list;
  list = NULL;
  char name[20];
  char number[20];

  while (fscanf(in, "%s %s", name, number) == 2) 
    list = add(list, name, number);
  

  list = add(list, "Mike", "234234");
  list = add(list, "Jack", "345345");
  list = add(list, "Ben", "456456");
  list = add(list, "Willow", "567567");

  print(list);
  return 0;


Student* add(Student *list, char *name, char *number) 
  Student* new = makeNode(name, number);

  if (list == NULL) 
    list = new;
   else 
    Student *head = list;
    while (head->next != NULL)  // traverse to the end of the list
      if (strcmp(name, head->name) <= 0)  break; 
      head = head->next;
    

    if (strcmp(name, head->name) <= 0) 
      // prepend
      if (head->prev != NULL) 
        new->prev = head->prev;
        new->next = head;
        head->prev->next = new;
        head->prev = new;
       else 
        new->next = head;
        head->prev = new;
        list = new;
      
     else 
      if (head->next != NULL) 
        new->next = head->next;
        new->prev = head;
        head->next->prev = new;
        head->next = new;
       else 
        new->prev = head;
        head->next = new;
      
    
  

  return list;


Student* makeNode(char *name, char *number) 
  Student *node = (Student*) malloc(sizeof(Student));

  node->name = name;
  node->number = number;
  node->prev = NULL;
  node->next = NULL;

  return node;


void print(Student *list) 
  Student *current;

  if (list == NULL) 
    printf("List is empty.\n");
   else 
    current = list;

    while (current != NULL) 
      printf("[%s - %s]\n", current->name, current->number);
      current = current->next;
    
  

【问题讨论】:

编辑问题以提供minimal reproducible example。 @EricPostpischil 我已经添加了我的整个代码。 一种可能性是使用非标准的strdup() 函数来制作字符串数据的副本。 node-&gt;name = strdup(name); 【参考方案1】:

一种简单的方法是更改​​ makeNode 函数以使其分配 char 数组:

Student* makeNode(char *name, char *number) 
  Student *node = (Student*) malloc(sizeof(Student));
  node->name = malloc(1 + strlen(name));
  node->number = malloc(1 + strlen(number));

  strcpy(node->name, name);
  strcpy(node->number, number);
  node->prev = NULL;
  node->next = NULL;

  return node;

但不要忘记在释放节点之前释放它们...

【讨论】:

谢谢。这就像一个魅力。我假设节点上的mallocing 会自动为里面的变量分配内存。 @MiniGunnR:没有 malloc 只为节点本身分配内存,所以这里只为指针分配内存。由程序员为字符串分配内存。但是不要忘记在释放节点之前释放它们...

以上是关于如何使用文件中的while循环为我的结构分配值?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 中的另一个 while 循环中正确地创建一个 while 循环?

在 DataBricks 中,如何为变量分配来自外部文件的字符串值?

无法将文件中的多个值分配给 json 请求

PHP - 在while循环中分配值并在循环外单独访问它们

如何在while循环中返回?

如何为单选按钮分配一个值并稍后在 Android 中检索该值?