I / O重载和从文本文件中读取

时间:2011-08-10 11:22:31

标签: c++

我需要为具有对象数组作为私有变量的类定义读取和打印函数。我必须从文本文件中读取对象并将它们打印到屏幕上。要做到这一点,我需要重载<<和>>运营商。我知道我需要使用循环来读取和打印存储在数组中的信息,但我不知道如何实现这一点。我的讲师给了我们一个骨架代码,基本上是函数原型和我需要坚持的主要功能。我理解这是如何使用公共结构的,因为我已经使用它完成了这个确切的场景,但是类'的私有变量正在绊倒我。

class EmployeeList {
public:
  //Constructors
  EmployeeList();
  EmployeeList(istream&);
  //Accessors
  bool isEmpty() const;
  bool isFull() const;
  int size() const; //Number of employees in list
  Employee item(int i) const; //i'th employee
  //Mutators
  void setItem(int i,const Employee& e);
  //I/O functions, sets the i'th emplyee to e
  void read(istream&);
  void print(ostream&) const;

private:
  enum {MAXSIZE = 100};
  Employee list[MAXSIZE];
  int count; //Number of employees in the current list
};

EmployeeList::EmployeeList() {
  count = 0;
}

EmployeeList::EmployeeList(istream& in) {
  //list[MAXSIZE] = in;
}

bool EmployeeList::isEmpty() const {
  return (count == 0);
}

bool EmployeeList::isFull() const {
  return (count == MAXSIZE);
}

int EmployeeList::size() const {
  return count;
}

Employee EmployeeList::item(int i) const {
}

void EmployeeList::setItem(int i, const Employee& e) {
}

void EmployeeList::read(istream& in) {
  Employee tempList;
  while (in >> tempList) {
  }
}

void EmployeeList::print(ostream& out) const {
  for (int i=0; i < size(); i++) {
  }

  cout << out;
}

上面的部分是Class EmployeeList,而下面的部分是重载函数。注释掉的部分是我认为可能有效但没有的想法。

istream& operator>>(istream& in, EmployeeList& l) {
  l.read(in);
  return in;
}

ostream& operator<<(ostream& out, const EmployeeList& l) {
  l.print(out);
  return out;
}

以下是给我们的主要功能。

int main() {
  authorInfo();
  ifstream infile("a1in.txt");
  if(!infile) {
      cout << "file 'alin.txt' not found.";
      return EXIT_FAILURE;
  }
  EmployeeList theList(infile);

  cout << endl;
  cout << theList.size() << " employees read:\n" << theList << endl;
  process(theList);
  return EXIT_SUCCESS;

}

希望有人能引导我朝着正确的方向前进!如果您需要更多代码,请告诉我们。谢谢!

编辑: 员工阅读和打印功能:

void Employee::read(istream& in) {
  in >> name >> id >> salary;
}

void Employee::print(ostream& out) const {
  out << getName() <<" "<< getID() <<" "<< getSalary() << endl;
}

员工超载:

istream& operator>>(istream& in, Employee& e) {
  e.read(in);
  return in;
}

ostream& operator<<(ostream& out, const Employee& e) {
  e.print(out);
  return out;
}

编辑2:更新了read()函数。带有while的行是出错的地方。

void EmployeeList::read(istream& in) {
  Employee inEmployee;
  while (in >> inEmployee && count < MAXSIZE) {
      list[count] = inEmployee;
      count++;
  }
}

编辑3:这是我到目前为止的print()函数。它确实打印但我得到默认的构造函数信息而不是文件中的信息。这是读取还是打印功能问题?我还在考虑阅读功能。

void EmployeeList::print(ostream& out) const {
  cout << endl;
  for (int i=0; i < count; i++) {
      out << list[count];
  }
} 

4 个答案:

答案 0 :(得分:1)

数组边界

在你的课堂上,你有:

Employee list[MAXSIZE];

鉴于此,您尝试的代码出错:

EmployeeList::EmployeeList(istream& in) {
  list[MAXSIZE] = in;
}

list仅包含list[0]list[MAXSIZE - 1]的元素。 list[MAXSIZE]是数组末尾的一个,并且无效。

构造

那就是说,我强烈建议不要使用一个istream&的构造函数。使用默认构造函数构造空对象要好得多,然后使用其read(istream&)方法(通过operator <<)来加载数据。换句话说,而不是:

EmployeeList theList(infile);

使用:

EmployeeList theList;
infile >> theList;

如果您必需拥有一个istream&的构造函数,请在初始化对象后调用read()

EmployeeList::EmployeeList(istream& in): count(0) {
  read(in);
}

请注意,只有一个构造函数被称为,因此EmployeeList::EmployeeList()中的初始化不会发生在EmployeeList::EmployeeList(istream&)中。我听说C ++的新版本处理了这种不必要的重复,但暂时还是我们所处的位置。

命名

另一件事:使用更好的变量名称,您的代码将更少混淆。在这种情况下:

void EmployeeList::read(istream& in) {
  Employee tempList;
  while (in >> tempList) {
  }
}

不要说tempList,因为它是一个“临时列表”,它是一个已被阅读的Employee。更好的是:

void EmployeeList::read(istream& in) {
  Employee inEmployee;
  while (in >> inEmployee) {
    list[count++] = inEmployee;
  }
}

答案 1 :(得分:0)

您可以先了解如何阅读输入内容。我认为可能不完整的方法是:

EmployeeList::EmployeeList(istream& in) {
  count = 0;
  read(in);    // delegate it to avoid duplication
}

void EmployeeList::read(istream& in) {
  Employee tempList;
  while (in >> tempList && count < MAXSIZE) {
    list[count] = tempList;
    ++count;
  }
}

您需要为operator>>课程重载Employee才能使其生效。

答案 2 :(得分:0)

这看起来像是一个家庭作业所以我会试着给你一个提示:

void EmployeeList::read(istream& in) {

  Employee tempList;
  while (in >> tempList) {
  //here you are creating a tempList so after you fill in the values in tempList 
  //the tempList is to become a part of Employee list[MAXSIZE]; 
  }
}

你如何填写价值观?您可以使用构造函数执行此操作并维护count

EmployeeList::EmployeeList(istream& in) {
  //here...
}

答案 3 :(得分:0)

以下是我在没有骨架约束的情况下写这个的方法。随意适应您的作业要求。

来源:http://www.ideone.com/R9EeF

Iostream很难掌握。您必须阅读std::getlinestd::ios标志和字符串流,以了解如何使用它们解析员工列表。

我更喜欢给你一个工作模板(由于我根本没有使用骨架,你不能用于你的作业),因为有很多关于iostreams的说法。

也可以随意提问,这样我就可以用实际问题来提高答案。