我无法弄清楚为什么我的代码将两次打印输出到控制台。我确定这是我错过的一些小细节,但我一整天都在工作,我需要一双新鲜的眼睛。
代码如下:
#include <iostream>
#include <string>
#include <sstream>
//Allows use of basic C++ functions
using namespace std;
//Base class for all classes
class Person
{
protected:
string m_Name, m_Surname, m_Telephone, m_Email;
public:
Person() {}
Person(string &s, string &f) : m_Surname(s), m_Name(f)
{
m_Name = "NoName", m_Surname = "NoSurname", m_Telephone = "", m_Email = "";
}
void set_name(string &f)
{
m_Name = f;
}
void set_surname(string &s)
{
m_Surname = s;
}
virtual string get_name()
{
return m_Name;
}
virtual string get_surname()
{
return m_Surname;
}
virtual string get_telephone()
{
return m_Telephone;
}
virtual string get_email()
{
return m_Email;
}
virtual bool has_telephone_p()
{
if (m_Telephone.empty())
{
//cout << "NoNumber" << endl;
return false;
}
else
{
//cout << "Your phone number is now registered"<< endl;
return true;
}
}
virtual bool has_email_p()
{
if (m_Email.empty())
{
//cout << "NoEmail" << endl;
return false;
}
else
{
//cout << "Your email is now registered" << endl;
return true;
}
}
};
//Inherits from class Person
class Person_with_telephone : public virtual Person
{
protected:
string telephone = m_Telephone;
public:
Person_with_telephone() {}
Person_with_telephone(string &s, string &f, string &t) : Person(s, f), telephone(t) {}
void set_telephone(string &telephone)
{
m_Telephone = telephone;
}
};
//Inherits from class Person
class Person_with_email : public virtual Person
{
protected:
string email = m_Email;
public:
Person_with_email() {}
Person_with_email(string &s, string &f, string &e) :Person(s, f), email(e) {}
void set_email(string &e)
{
m_Email = e;
}
};
//Inherits from classes Person_with_telephone and Person_and_email
class Person_with_telephone_email : public virtual Person_with_telephone, public virtual Person_with_email
{
protected:
public:
Person_with_telephone_email() {}
Person_with_telephone_email(string &s, string &f, string &t, string &e) : Person(s, f), Person_with_telephone(s, f, t), Person_with_email(s, f, e) {}
};
ostream &operator << (ostream &output, Person &p)
{
//Checks that both 'telephone' and 'email' are initialized to NoNumber and NoEmail respectively. If true, it prints name and surname
if (p.has_telephone_p() == false && p.has_email_p() == false)
{
output << "<person" << " S " << p.get_surname() << " N " << p.get_name() << " >" << endl;
return output;
}
//Checks that 'email' is initialized to NoEmail. If true, it prints name, surname, and telephone
else if (p.has_email_p() == false)
{
output << "<person" << " S " << p.get_surname() << " N " << p.get_name() << " T " << p.get_telephone() << " >" << endl;
return output;
}
//Checks that 'telephone' is initialized to NoNumber. If true, it prints name, surname, and email
else if (p.has_telephone_p() == false)
{
output << "<person" << " S " << p.get_surname() << " N " << p.get_name() << " E " << p.get_email() << " >" << endl;
return output;
}
//Checks to see that all 4 variables are initialized to non default values. If true, it prints all 4 values
else
{
output << "<person" << " S " << p.get_surname() << " N " << p.get_name() << " T " << p.get_telephone() << " E " << p.get_email() << " >";
return output;
}
}
istream& operator>>(istream &is, Person &p) {
string opening, s, surname, f, name, closing;
if (
(is >> opening >> s >> surname >> f >> name >> closing)
&&
((opening == "<person") && (s == "S") && (f == "N") && (closing == ">"))
)
{
p = Person(surname, name);
}
return is;
}
istream& operator>>(istream &is, Person_with_email &p) {
string opening, s, surname, f, name, e, email, closing;
if (
(is >> opening >> s >> surname >> f >> name >> e >> email >> closing) &&
((opening == "<person") && (s == "S") && (f == "N") && (e == "E") && (closing == ">"))) {
p = Person_with_email(surname, name, email);
}
return is;
}
istream& operator>>(istream &is, Person_with_telephone &p) {
string opening, s, surname, f, name, t, telephone, test_token;
if ((is >> opening >> s >> surname >> f >> name >> t) && (opening == "<person") && (s == "S") && (f == "N") && (t == "T")) {
if ((is >> test_token) && (test_token == "+")) {
is >> telephone;
}
else {
telephone = test_token;
}
p = Person_with_telephone(surname, name, telephone);
}
return is;
}
istream& operator>>(istream &is, Person_with_telephone_email &p) {
string opening, s, surname, f, name, t, telephone, e, email, closing, test_token;
if ((is >> opening >> s >> surname >> f >> name >> t) && (opening == "<person") && (s == "S") && (f == "N") && (t == "T")) {
if ((is >> test_token) && (test_token == "+")) {
is >> telephone;
}
else {
telephone = test_token;
}
if ((is >> e >> email >> closing) && ((e == "E") && (closing == ">"))) {
p = Person_with_telephone_email(surname, name, telephone, email);
}
}
return is;
}
Person* make_person(istream &stream) {
Person *person_pointer = new Person;
stream >> *person_pointer;
return person_pointer;
}
Person_with_email* make_person_email(istream &stream) {
Person_with_email *person_pointer = new Person_with_email;
stream >> *person_pointer;
return person_pointer;
}
Person_with_telephone* make_person_telephone(istream &stream) {
Person_with_telephone *person_pointer = new Person_with_telephone;
stream >> *person_pointer;
return person_pointer;
}
Person_with_telephone_email* make_person_telephone_email(istream &stream) {
Person_with_telephone_email *person_pointer = new Person_with_telephone_email;
stream >> *person_pointer;
return person_pointer;
}
istream &read_person(istream &in, Person * & p) {
string input;
getline(in, input);
cout << "input:\n" << input;
if (input == " ") { return in; }
stringstream stream(input);
string s = " S ";
string e = " E ";
string t = " T ";
bool is_valid_person = false;
bool has_t = false;
bool has_e = false;
if (input.find(e) != string::npos) { has_e = true; }
if (input.find(t) != string::npos) { has_t = true; }
if (input.find(s) != string::npos) { is_valid_person = true; }
if (has_e && has_t) {
cout << "e + t\n";
Person_with_telephone_email *person_pointer = make_person_telephone_email(stream);
p = person_pointer;
}
else if (has_e) {
cout << "e\n";
Person_with_email *person_pointer = make_person_email(stream);
p = person_pointer;
}
else if (has_t) {
cout << "t \n";
Person_with_telephone *person_pointer = make_person_telephone(stream);
p = person_pointer;
}
else if (is_valid_person) {
cout << "is person \n";
Person *person_pointer = make_person(stream);
p = person_pointer;
}
else {
cout << "\nInvalid input.\n";
}
return in;
}
int main() {
//Tests the read_person istream
Person *p = 0;
string ss = "<person S Smith N Tom >\n<person S Smith N Dick T +49.921.1434 >\n<person S Smith N Harry E hsmith@gmail.com >\n<person S Smith N Mary T +39.921.1434 E msmith@gmail.com >\n<person S John N John T + 33.921.1434 E jjohn@gmail.com >";
stringstream iss(ss);
while (read_person(iss, p) && p)
cout << *p << endl;
return 0;
}
输出看起来像this,它的外观应该是相同的,但没有说明NoName
和NoSurname
的行。
我真的不知道为什么会这样,你有什么建议吗?
答案 0 :(得分:0)
老兄,我认为有280行代码供审查有点太多了:P我也无法完全明白“代码是两次打印输出”是什么意思。它正在打印两种不同的输出,至少这就是我所看到的。
现在到了这一点,我希望它会有所帮助:你有两个重要的couts:
while循环中的第一个:
cout << *p << endl;
和read_person函数体中的第二个:
cout << "input:\n" << input;
我评论了其中一个然后打印结果完全不同。据我了解你的代码,最终行为不正确 - 检查输出cout << *p << endl;
注释掉:))