c++ - 为类中的字符串成员重载运算符>>时出错

标签 c++ class operator-overloading inputstream

当我输入字符串类型的值时,例如:

_ho I typed Peter
_hoten I typed Peter Parker
_ten I typed Marry

我在屏幕上的输出是:

Peter Peter Marry

这是我的代码:

class SinhVien
{
private:
    string _ho;
    string _tenlot;
    string _ten;
public:
    static int InstanceCount;
    SinhVien();
    string ToString() const;
    friend istream& operator>>(istream& in, SinhVien* p);
    friend ostream& operator<<(ostream& out, const SinhVien* p);
    ~SinhVien();
};
istream& operator>>(istream& in, SinhVien *p)
{
    cout << "Nhap ho: \n";
    in >> p->_ho;
    rewind(stdin);
    cout << "Nhap ten lot: \n";
    in >>  p->_tenlot;
    rewind(stdin);
    cout << "Nhap ten: \n";
    in >> p->_ten;
    return in;
}
string SinhVien::ToString() const
{
    stringstream writer;
    writer << _ho << " " << _tenlot << " " << _ten << "\n";
    return writer.str();
}
ostream& operator<<(ostream &out, const SinhVien* p)
{
    out << p->ToString();
    return out;
}

void main()
{
    SinhVien *a;
    a = new SinhVien();
    cin >> a;
    cout << a;
    cout << "\nTo string:\n";
    cout << a->ToString();
    delete a;
    system("pause");
}

最佳答案

在您的 std::basic_istream::operator>> 重载中,您需要使用 std::geline()而不是 std::cin >>,这样您就可以获得完整的输入名称,并带有空格

其次,您应该传递对象指针的引用,以便更改将应用​​于传递的对象,而不是其拷贝。

修复:

std::istream& operator>>(std::istream& in, SinhVien* &p)
{                                                // ^^ take ref of object you pass, so that the change will be applied to the object, not to the copy of it.
    std::cout << "Nhap ho: \n";
    std::getline(in, p->_ho);   // change
    std::rewind(stdin);
    std::cout << "Nhap ten lot: \n";
    std::getline(in, p->_tenlot);   // change
    std::rewind(stdin);
    std::cout << "Nhap ten: \n";
    std::getline(in, p->_ten);   // change
    return in;
}

以上适用于单个输入。但是,多个输入的情况以及在 main() 中使用 std::cin >> 可能会再次导致一些输入跳过问题。感谢@Yksisarvinen 指出了这一点。 您可以在这篇文章中阅读更多内容:Why does std::getline() skip input after a formatted extraction?


旁注:在现代 C++ 中,您不再需要管理原始指针。因为你有 smart pointers 它将在对象超出范围时管理它的生命周期。因此,只要有可能就使用它。

这意味着您可以执行以下操作: SEE LIVE

#include <memory>

class SinhVien
{
private: // memebrs
public:
    // other member functions
    friend istream& operator>>(istream& in, const std::unique_ptr<SinhVien> &p);
    friend ostream& operator<<(ostream& out, const std::unique_ptr<SinhVien> &p);
};

std::istream& operator>>(std::istream& in, const std::unique_ptr<SinhVien> &p)
{                                                                          
    std::cout << "Nhap ho: \n";
    std::getline(in, p->_ho);   // change
    std::cout << "Nhap ten lot: \n";
    std::getline(in, p->_tenlot);   // change
    std::rewind(stdin);
    std::cout << "Nhap ten: \n";
    std::getline(in, p->_ten);   // change
    return in;
}

std::ostream& operator<<(std::ostream &out, const std::unique_ptr<SinhVien> &p)
{
    return out << p->ToString();
}

int main()
{
    auto a = std::make_unique<SinhVien>();
    std::cin >> a;
    std::cout << a;
    std::cout << "\nTo string:\n";
    std::cout << a->ToString();
    return 0;
}

关于c++ - 为类中的字符串成员重载运算符>>时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53139444/

相关文章:

c++ - #if 预处理器指令可以嵌套在 C++ 中吗?

c++ - C++遍历中的树排序

c++ - 包含来自另一个文件的运算符重载

c++ - 我无法从串口发送连续数据

c++ - C++ 可以分配页面锁定内存吗?

c++ - (C++) 这些重载运算符函数有什么区别?

c++ - 类中的 Typedef

ios - 无法将类型 'UIView' 的值分配给类型 --class 符合 UIView--

c++ - 重载时 operator+= 的返回类型

iterator - CUDA Thrust sort_by_key 当键是由 zip_iterator 用自定义比较谓词处理的元组时