首页 > 解决方案 > 如何将多个变量读入一个节点?

问题描述

所以我的项目是获取一个名为“contacts.txt”的文件,读入数据并将数据放入一个节点。然后,我将该节点放入列表中。我清除重复项并打印出结果列表。我正在尝试先读取数据和打印部分,但打印列表时遇到问题。

联系方式如下: Angelina M. Pierre 306 420 1235

并且该行的每个部分(名字、中间名首字母、姓氏、电话号码)都应该有自己的变量。我不确定我做错了什么,我将不胜感激。我的代码是:

#include <iostream>
#include <bits/stdc++.h>
#include <stdlib.h>
#include <fstream>
using namespace std;


class Node
{
public:
  string firstName;
  string middleI;
  string lastName;
  string phoneNum;
    Node *next;
};


// This function prints contents of linked list
// starting from the given node
void printList(Node* n)
{
    while (n != NULL) {
        cout << n->firstName->middleI->lastName->phoneNum << endl;
        n = n->next;
    }
}

//This function reads the data from a file called "contacts"
//And streams each line into a new node.
void readData(Node* &p)
{
  Node *newNode = new Node; /* Initializing the node*/

  ifstream fin("C:\\Users\\owner\\Documents\\contacts.txt");


  p = newNode;
  while(!EOF){
//fin >> firstName >> middleI >> lastName >> phoneNum; 
  //while(getline(fin,newNode->contacts)){
newNode->firstName;
newNode->middleI;
newNode->lastName;
newNode->phoneNum;
     newNode->next = new Node;
     newNode = newNode->next;
  }
}

// Driver code
int main()
{
    Node *head;
    readData(head);
    printList(head);
    return 0;
}

标签: c++linked-listnodes

解决方案


我认为有几件事主要会降低您程序的性能。在您的printList函数中,您有行cout << n->firstName->middleI->lastName->phoneNum << endl;,我假设您打算在这里打印用户的所有信息。然而,这里发生的事情是程序获取指针n,尝试查找firstName所指向对象的属性,然后获取该属性并尝试查找该middleI属性的属性,然后是该lastName属性的属性,等等。这些字段当然不存在,因此您的程序可能会崩溃。相反,我认为使用类似的东西cout << n->firstName << " " << n->middleI << " " << n->lastName << " " << n->phoneNum << endl;会更好。

此外,在您的readData函数中,您的 while 循环将继续更新单个节点p,而不是创建新节点,因此(假设您的输入文件格式正确且所有爵士乐)您的头节点,这是传递给此函数时的内容它由 调用main(),仅等于文件中的最后一个联系人,并且您的列表的长度为 1。


顺便说一句,我看到你只有一个Node类。如果您想使用列表,您可能应该创建第二个类(即LinkedList),它需要一个更高级别的抽象。然后,您的Node班级将处理设置/报告其数据并回答跟随它的节点,您的LinkedList班级将处理跟踪列表(通过记住头部的位置),添加到列表中/从列表中删除,以及查找特定节点在列表中。


其他一些考虑:

  1. 类持有的变量几乎总是私有的而不是公有的。首先封装信息的原因,除了组织它之外,是为了确保程序的其他部分无法更改这部分代码,并且当您将所有内容公开时,您将失去这种保护.
  2. 您用来创建/添加节点、打印列表等的函数都应该是方法(即特定类的函数)。假设我有一些类 ,Foo它有一个作用于它的函数,名为bar。为了实现它,我可以编写如下内容:
class Foo {
    private:
        //Foo's variables
    public:
        void bar() {
            //bar's implementation
        }
    }

您将能够在其他地方使用该方法 bar(),因为它被标记为public,并将bar()负责处理对Foo的信息的任何必要操作。

  1. 使用它被认为是不好的做法,using namespace std;因为它有时会导致模棱两可的函数调用并且添加std::更加明确。请参阅此处了解更多信息。
  2. 使用关键字NULL是非常 C 风格的,而nullptr在 C++ 中被认为更合适(甚至更安全)。如果你很好奇,似乎对这种变化给出了相当深入的解释。
  3. usingwhile(!fin.eof())也被认为是错误的,因为只有在您完成读取输入文件!fin.eof()才会返回 true 。因此,您将尝试读取文件末尾的内容,这很危险。请参阅此处了解更多信息。

有点冗长,但我希望这能为您澄清一点!如果您有任何问题,请随时发表评论。


推荐阅读