【问题标题】:C++ Extraction Operator for Class Functions类函数的 C++ 提取运算符
【发布时间】:2014-07-18 12:25:24
【问题描述】:

我不确定运算符重载是否是我正在寻找的,但我需要知道在 C++ 中实现以下目标的最佳方法;

我有一个只有 ID 号 atm 的 Employee 类(为简单起见)。请假设输入文件有一个 int 数字和后面的一些字符(仅显示 1 行),例如:

1234 查尔斯·哈蒙德

这是目前为止的代码。我正在尝试使用提取运算符将整数和其他数据从输入文件获取到我的类函数(SetID);

class Employee
{
    int employeeID;

public:
     void SetID(int);
}

void Employee::SetID(int empID)
{
    employeeID = empID;
}

int main(void)
{
    int lineCounter = 4;
    Employee emp;

    //Create filestream objects and open
    ifstream input;
    ofstream output;
    input.open("input.txt");
    output.open("output.txt");


    for (int i = 0; i < lineCounter; i++)
    {
        input >> emp.SetID(input.get()); //illegal? Best way to do this
    }


    //Close program
    output.close();
    input.close();
    system("pause");
    return 0;
}

我只是想从输入文件中获取 ID 并将其存储在类成员“employeeID”中,以便以后用于计算。

【问题讨论】:

  • 你会得到例子here

标签: c++ file-io io operator-overloading iostream


【解决方案1】:

一种选择是重载 &gt;&gt; 运算符并使其成为 Employee 类中的友元函数。

类似:

istream& operator>>( istream& in, Employee& emp )
{
    in >> emp.employeeID;
    return in;
}

在您的 Employee 类中:

friend istream& operator>> (istream& in, Employee& emp);

【讨论】:

    【解决方案2】:

    有很多方法可以做到这一点,每种方法都有优点和缺点。您正在读取的数据格式表明您每行有一个“记录”,在这种情况下应该以某种方式强制执行。下面通过从输入文件中读取一行数据,然后通过字符串流发送该行以进行进一步处理来实现这一点:

    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <string>
    
    class Employee
    {
        // friend this operator, as we'll give it access to our
        //  private data members of our class.
        friend std::istream& operator >>(std::istream& inp, Employee& obj);
    
        int employeeID;
    
    public:
        void setID(int id) { employeeID = id; }
        int getID() const { return employeeID; }
    };
    
    // extracts a single employee from a single input line taken from
    //  the passed input stream. the code below mandates one, and only
    //  one employee per line.
    std::istream& operator >>(std::istream& inp, Employee& obj)
    {
        // used as a full-line-buffer to enforce single-record-per-line
        std::string line;
        if (std::getline(inp, line))
        {
            // think of it as an in-memory stream primed with our line
            // (because that's exactly what it is).
            std::istringstream iss(line);
    
            // TODO: eventually you'll want this to parse *all* values from
            //  the input line, not just the id, storing each in a separate
            //  member of the Employee object being loaded. for now we get
            //  only the id and discard the rest of the line.
            if (!(iss >> obj.employeeID))
            {
                // a failure to read from the line string stream should flag
                //  the input stream we read the line from as failed. we also
                //  output the invalid line to std::cerr.
                inp.setstate(std::ios::failbit);
                std::cerr << "Invalid format: " << line << std::endl;
            }
        }
        return inp;
    }
    
    
    int main()
    {
        // open input and output files
        std::ifstream input("input.txt");
    
        // read at-most four employee lines from our file. If there are
        //  less than that or a read-error is encountered, we will break
        //  early.
        Employee emp;
        for (int i=0; i<4 && input >> emp; ++i)
        {
            // do something with this thing
            std::cout << "Read Employee: " << emp.getID() << '\n';
        }
    
        system("pause");
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-17
      • 2020-09-24
      • 2016-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-12
      相关资源
      最近更新 更多