从fstream读/写 - 需要帮助

时间:2014-03-07 04:43:02

标签: c++ stream fstream istream

在C ++课程的项目上工作我遇到了障碍。我们正在练习具有固定长度员工记录的文件i / o。我正在创建Employees,将它们存储到unique_ptr的向量中,然后尝试遍历这些,写入文件,清除向量,然后将它们从文件中读回到向量中。

问题似乎在于我如何尝试重读它们。写完之后,文件中的所有内容看起来都是正确的。以下是我试图做的事情。 然而,在读取Employee记录后,它会循环一次额外的时间并且无法识别文件的结尾,用垃圾数据填充成员。我无法弄清楚为什么,因为我是写出确切的字节数然后读回相同的数字。

当将员工记录读回文件中的向量时,做错了:

while (emprecs.good())

我怀疑这是让我遇到麻烦的原因,但是无法弄清楚如何测试/调试它。以下是适用的代码:

Employee.h

class Employee{
    int id;
    std::string name;
    std::string address;
    std::string city;
    std::string state;
    std::string country;
    std::string phone;
    double salary;

    struct EmployeeRec{ // Employee file for transfers
        int id; 
        char name[31];
        char address[26];
        char city[21];
        char state[21];
        char country[21];
        char phone[21];
        double salary;
};

    void write(std::ostream&) const;
    static std::unique_ptr<Employee> read(std::istream&);
};

Employee.cpp

// Write a fixed-length record to current file position
void Employee::write(ostream& os) const{
    EmployeeRec outbuf;
    outbuf.id = id;
    strncpy(outbuf.name, name.c_str(), 30)[30] = '\0';
    strncpy(outbuf.address, address.c_str(), 25)[25] = '\0';
    strncpy(outbuf.city, city.c_str(), 20)[20] = '\0';
    strncpy(outbuf.state, state.c_str(), 20)[20] = '\0';
    strncpy(outbuf.country, country.c_str(), 20)[20] = '\0';
    strncpy(outbuf.phone, phone.c_str(), 20)[20] = '\0';
    outbuf.salary = salary;
    os.write(reinterpret_cast<const char*>(&outbuf), sizeof outbuf);
}

// Read record from current file position
std::unique_ptr<Employee> Employee::read(std::istream& is){
    EmployeeRec inbuf;
    is.read(reinterpret_cast<char*>(&inbuf), sizeof inbuf);
    unique_ptr<Employee> emp(new Employee());
    if (is.good()) {
        emp->id = inbuf.id;
        emp->name = inbuf.name;
        emp->address = inbuf.address;
        emp->city = inbuf.city;
        emp->state = inbuf.state;
        emp->country = inbuf.country;
        emp->phone = inbuf.phone;
        emp->salary = inbuf.salary;
    }
    return emp;
}

Driver.cpp

// employee.bin is a new file that I will be writing to and then reading from
// Write all employee's currently in the vector to the file
fstream emprecs("employee.bin", ios::in | ios::out | ios::binary | ios::trunc); 
    _ASSERT(emprecs.is_open()); 
    for (size_t i = 0; i < EmpVect.size(); ++i){
                // EmpVect is a vector of unique_ptr<Employee>
        (EmpVect[i])->write(emprecs);
    }

// Clear the vector in preparation to read the employees back in from the file
EmpVect.clear();

// Move back to beginning of stream
emprecs.seekp(0, ios::beg);

// Read employees back in from the file
// This loops an extra time with junk data... can't figure out why, though
// Shouldn't the failbit be set once I reach end of file? I am missing something here.
while (emprecs.good()){
    EmpVect.push_back(std::move(Employee::read(emprecs)));
}

1 个答案:

答案 0 :(得分:2)

std::unique_ptr<Employee> Employee::read(std::istream& is)

is.good()返回false时,emp仍然返回,这是一个结构,不会用constucter初始化(所以使用垃圾数据)。