【问题标题】:C++ Reading from txt file into object binary treeC ++从txt文件读取到对象二叉树
【发布时间】:2015-04-24 16:22:35
【问题描述】:

***用我的更改编辑了代码——不再出现访问冲突,它完美地分配了我的所有值,除了客户 ID——它只是把那个留空。那是因为 ID 是数字而不是技术上的字符串吗??

这是作业——我们应该从 .txt 文件中读取数据,然后将记录分配给对象,然后将对象写入二叉树。这是输入文本文件格式:

00001
Wilee Caytote
123 E. Fifth St.
Phynox
AZ
12345-1234
00002
Dave Wells
444 W. Third St.
Dayton
OH
45402
00012
Robert U. McKey
4986 Boundary St.
Jacksonville
AZ
12345
00123
Ruby B. Edwards
4861 Spring Ave.
Philadelphia
PA
19108

每一行都是客户(ID、姓名、地址)和地址(街道、城市、州、邮编)类的成员。我正在覆盖我的 cin >> 运算符以获取值,但这些值没有分配给对象成员。我确定我的程序可以读取文本文件,因为我执行了以下操作,并将我的文件打印到控制台。

myfile.open ("Customers.txt");
while(getline(myfile, line)) 
    {
cout << line << '\n';
    }
myfile.close();

这是我的 Customer.h 类,其中 cin 重载是:

#pragma once
#include <string>
#include <iostream>
#include <fstream>
#include "Address.h"

using namespace std;

class Customer
{

private:
//Attributes for customers
string custID;
string custName;
Address* address;

public:
//Constructors for Customer
Customer();
Customer(string, string, Address*);
~Customer();
//Setters for Customer
void setCustID(int);
void setCustName(string);
void setCustAddress(Address*);
//Getters for Customer
string getCustID() { return custID; }
string getCustName() { return custName; }

//Operator overloads
bool operator>(Customer obj) { return custID > obj.custID; }
bool operator<(Customer obj) { return custID < obj.custID; }
bool operator==(Customer obj) { return custID == obj.custID; }

//Operator overloads for input
friend istream &operator>>(istream &input, Customer &customer) {
    getline(input, customer.custID);
    getline(input, customer.custName);
    (*customer.address);
    return input;
}

//Operator overloads for output
friend ostream &operator<<(ostream &output, Customer &customer) {
    output << "CustID: " << customer.custID << endl << "Customer Name: " << customer.custName << endl << (*customer.address);
    return output;
}
};

这是我的 Address.h 类:

#pragma once
#include <string>
#include <iostream>
#include <fstream>

using namespace std;

class Address 
{
private:
string street;
string city;
string state;
string zip;

public:
//Constructors for address
Address();
Address(string, string, string, string);
~Address();
//Setters for address
void setAddressStreet(string);
void setAddressCity(string);
void setAddressState(string);
void setAddressZip(string);
//Getters for address
string getAddressStreet() {return street;}
string getAddressCity() {return city;}
string getAddressState() {return state;}
string getAddressZip() {return zip;}

//Operator overload for input
friend istream &operator>>(istream &input, Address &address) {
    getline(input, address.street);
    getline(input, address.city); 
    getline(input, address.state);
    getline(input, address.zip);
    return input;
}
//Operator overload for output
friend ostream &operator<<(ostream &output, Address &address) {
    output << "Street Address: " << address.street << endl << "City: " << address.city << endl << "State: " << address.state << endl << "Zip: " << address.zip << endl;
    return output;
}
};

这是我的驱动程序,我正在读取文件,将行分配给对象,并将它们插入二叉树:

#include "Customer.h"
#include "BinaryTree.h"

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()  
{
BinaryTree tree;
Customer customer;
string id;

//Define file and line variables
ifstream myfile;
string line;

//Open file and read lines into objects
myfile.open ("Customers.txt");
while(myfile >> line) 
{
    myfile >> customer;
    tree.addCustomer(customer);
    cout << customer;
}
myfile.close();

system ("pause");
return 0;

}

客户.cpp:

#include "Customer.h"

//Customer no arg constructor
Customer::Customer()
{
custID = "";
custName = "";
address = new Address;
}

//Customer constructor
Customer::Customer(string custID, string custName, Address* address)
{
this->custID = custID;
this->custName = custName;
}

//Customer destructor
Customer::~Customer()
{
}

地址.cpp:

#include "Address.h"

//Address no arg constructor
Address::Address()
{
street = "";
city = "";
state = "";
zip = "";
}

//Address constructor
Address::Address(string street, string city, string state, string zip)
{
this->street = street;
this->city = city;
this->state = state;
this->zip = zip;
}

//Address destructor
Address::~Address()
{
}

【问题讨论】:

  • 您正在使用 &gt;&gt; 读取包含空格的字段,这不是您想要做的。对于任何包含空格的输入,您需要使用 getline()
  • 您使用 getline 读取单行(第一行仅包含“00001”,然后您覆盖的 Customer >> 运算符尝试从中提取 ID、名称和地址?
  • Customer 的默认构造函数是否曾初始化 Customer::address 指针?如果不是,那么当运算符 >> 使用它时,这肯定会导致内存冲突。
  • @NathanOliver,我想我以为我在 CustomerMenu.cpp 的 while 循环中使用了 getline——我想我不是!就像我说的,我可能在这里有一些逻辑问题。所以我需要为我的运算符重载中的每个输入使用 getline——对吗?
  • 拥有数据成员和类的方式我会使用getline() 进行所有读取,但读取地址时除外。您仍应使用&gt;&gt; 运算符作为地址,并在函数中调用getline()

标签: c++ operator-overloading iostream


【解决方案1】:

您需要在Customer 类中初始化地址指针。您正在取消引用导致访问冲突异常的未初始化指针。

在您的 customer 构造函数中,添加以下行:

address = new Address;

您需要将以下内容添加到 customer 析构函数:

delete address;

虽然,我很好奇为什么你的Address 成员是一个指针。直接声明它而不是创建指向它的指针会更安全,更不容易出错。如果您真的希望它是一个指针,我建议您查看 std::unique_ptr 而不是使用原始指针。

【讨论】:

  • 向我的客户构造函数添加地址初始化消除了访问冲突错误,谢谢!虽然,我尝试让我的地址成员不是指针,然后我在 = 符号上遇到了各种语法错误。我把它放回指针,一切都很开心。
猜你喜欢
  • 1970-01-01
  • 2013-01-25
  • 2016-08-11
  • 1970-01-01
  • 1970-01-01
  • 2016-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多