c++ - 如何将多个变量读入一个节点?
问题描述
所以我的项目是获取一个名为“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;
}
解决方案
我认为有几件事主要会降低您程序的性能。在您的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
班级将处理跟踪列表(通过记住头部的位置),添加到列表中/从列表中删除,以及查找特定节点在列表中。
其他一些考虑:
- 类持有的变量几乎总是私有的而不是公有的。首先封装信息的原因,除了组织它之外,是为了确保程序的其他部分无法更改这部分代码,并且当您将所有内容公开时,您将失去这种保护.
- 您用来创建/添加节点、打印列表等的函数都应该是方法(即特定类的函数)。假设我有一些类 ,
Foo
它有一个作用于它的函数,名为bar
。为了实现它,我可以编写如下内容:
class Foo {
private:
//Foo's variables
public:
void bar() {
//bar's implementation
}
}
您将能够在其他地方使用该方法 bar()
,因为它被标记为public
,并将bar()
负责处理对Foo
的信息的任何必要操作。
- 使用它被认为是不好的做法,
using namespace std;
因为它有时会导致模棱两可的函数调用并且添加std::
更加明确。请参阅此处了解更多信息。 - 使用关键字
NULL
是非常 C 风格的,而nullptr
在 C++ 中被认为更合适(甚至更安全)。如果你很好奇,这似乎对这种变化给出了相当深入的解释。 - using
while(!fin.eof())
也被认为是错误的,因为只有在您完成读取输入文件后!fin.eof()
才会返回 true 。因此,您将尝试读取文件末尾的内容,这很危险。请参阅此处了解更多信息。
有点冗长,但我希望这能为您澄清一点!如果您有任何问题,请随时发表评论。
推荐阅读
- java - E/ACameraMetadata:getConstEntry:找不到元数据标签 65578
- c# - 从网站获取 Token 并将其传递回 WPF
- php - 单击文本后如何将值放入变量中
- javascript - 有没有办法在不禁用 swiper-prev 的情况下在最后一张幻灯片上启动 Swiper 滑块?
- swift - 如何快速将麦克风的输入转换为另一种格式?
- sql - 除了使用 psql 之外,还有其他将数据导入 Postgres 的方法吗?
- azure - Azure 数据工厂数据流中“数据集”和“内联”源之间的区别?
- mips - %hi 和 %lo 的 MIPS 错误
- express - 在 Google Cloud Run 上运行的 Express 服务器在响应 204 状态代码时返回 502 Bad Gateway
- android - setState 不会在颤动中刷新 ListView.builder