为什么我打印简单链表的代码不起作用?

Why doesn't my code for printing a simple Linked List work?

#include <iostream>
using namespace std;

typedef struct NODE node;

typedef struct NODE {
  int marks;
  char name[100];
  node *next;
} node;

node *getinput() {
  node *n;
  n = (node *)malloc(sizeof(node));
  if (n) {
    cin >> n->marks; // STATEMENT 1
    gets_s(n->name);
    n->next = NULL;
  }
  return n;
}

node *populateList(node *list) {
  node *temp;
  node *newptr = getinput();
  if (list == NULL) {
    list = newptr;
    return list;
  }

  temp = list;
  while (temp->next) {
    temp = temp->next;

    //(COMMENT 1)temp->next = newptr;
  }

  temp->next = newptr;
  return list;
}

void printlist(node *list) {
  node *p = list;

  // temp = list;
  while (p->next) {
    cout << p->marks << endl; // STATEMENT 2

    //(COMMENT 3) cout << list->marks << endl;

    puts(p->name);
    p = p->next;
  }
}

void main() {
  int x = 1;
  node *n = NULL;

  for (; x <= 6; x++)
    n = populateList(n);

  printlist(n);
}

所以,我面临着一些问题:

  1. 我不能取6个成员想要的分数和名字,但是我可以取6个成员的名字,但不能取他们的分数。 (如果我删除 STATEMENT 1 AND/OR STATEMENT 2,则会显示相同的输出)。

  2. 我假设成员的标记被认为是链表指针node * list的垃圾值,因为它似乎是所有成员都一样。

那么我该如何解决程序中的问题呢?我知道这个问题对很多人来说似乎太微不足道了,我可以很容易地在互联网上查找链表程序,但我决心解决这个问题。我想进一步了解代码中的issues/optimizations,以便我自己纠正。

谢谢

您正在将 C++ 与 C 代码混合, 一些小的修复。 使用 std::string name 而不是 char name[100] 使用 n = new node()

最后,对于你 "bug" 你应该将 gets_s(n->name); 切换为 cin >> (n->name); 这将起作用并为标记和名称填写正确的值。 我很确定问题来自于使用 C++ 函数 cin 和 C 函数 gets_s 混合来自 stdin 的输入,看起来 gets_s 在第一个 [=15= 之后取值的分隔符] 被调用。

也不要忘记删除分配的节点。

您的代码中存在几个问题;导致错误处理输入的一个原因是您将 cingets_s 混合使用,这通常不会按预期工作;顺便说一句:gets_sgets 是“老式的 C-style 并且在较新的标准中已弃用(甚至删除)。例如,使用 std::getline 作为替代。

将整数值和字符串与白色space混合读取实际上有点棘手。例如,如果输入是 10 john doe,那么 cin >> marks 将读入 10,但会在输入缓冲区中留下空白;你将不得不跳过白色 spaces,例如通过 cin >> ws;否则,您的字符串输入将立即终止,或者 - 如果使用 getline - 在开头包含一个空白。然后,如果你写 string name; cin >> name,那么只会读取 john,因为字符串输入在第一个白色 space 处停止。所以我建议使用 getline 读取名称直到行尾,这样你才能真正得到 john doe 作为名称。

此外,请注意输入可能会失败(例如文件末尾或无效格式),这样 getinput 可能必须 return 一个无效节点(应由 nullptr).

很多事情,所以我稍微重写了您的代码以将上述事情考虑在内。希望能帮助到你;享受编码的乐趣!

struct node {
    int marks;
    string name;
    node *next;
};

node *getinput() {
    int marks;
    string name;
    if (! (cin >> marks >> std::ws)) {
        return nullptr;
    }
    if (! getline(cin, name, '\n')) {
        return nullptr;
    }
    return new node { marks, name, nullptr };
}

node *addToList(node *list, node* newNode) {
    if (list == NULL) {
        return newNode;
    }
    if (newNode == nullptr) {
        return list;
    }

    node* temp = list;
    while (temp->next) {
        temp = temp->next;
    }

    temp->next = newNode;
    return list;
}

void printlist(node *list) {
    node *p = list;
    while (p) {
        cout << p->marks << " " << p->name << endl;
        p = p->next;
    }
}

int main() {
    int x = 1;
    node *n = NULL;
    node *list = NULL;

    while (x <= 3 && (n = getinput()) != nullptr) {
        list = addToList(list, n);
        x++;
    }

    printlist(list);
}