首页 > 解决方案 > C++ - 通过从文件中读取来创建对象,但内流不会在文件末尾停止。`std::invalid_argument what() stoi`

问题描述

因此,以下只是我在使用更大的程序时遇到的问题的一个小例子。

通过使其输出****,我能够弄清楚在它到达文件末尾应该是什么之后,while循环继续进行。我无法让它在文件末尾停止。

这是 .data 文件包含的内容的示例

/***
56
John

43
Lisa

91
Jim

***/

这是代码

#include <string>
#include <map>
#include <iostream>
#include <ostream>
#include <fstream>
using namespace std;

class Contact {
public:
  int ID;
  string name;
  void setID(int newID) {
    ID = newID;
  }
  void setName(string newName) {
    name = newName;
  }
  friend istream& operator>>(istream& lineIn, Contact& newContact) {
    string tempName;
    string tempID;
    string emptyLine;
    getline(lineIn, tempID);
    newContact.setID(stoi(tempID));
    getline(lineIn, tempName);
    newContact.setName(tempName);
    getline(lineIn, emptyLine);
    return lineIn;
  }
};

const string CONTACT_FILE = "contacts.data";
std::map<int,Contact> ContactsMap;

int main() {
  ifstream fin( CONTACT_FILE );
  if (fin) {
    Contact c;
    while ( fin >> c  ) {
      std::cout << "\n********";
      ContactsMap[c.ID] = c;
    }
    fin.close();
  }
  cout << "\nContactsMap.at(56).name";

}

标签: c++

解决方案


问题是您没有检查重载中的错误operator>>。因此,getlines 失败,但您仍在尝试设置联系人中的值。试试这个

  friend istream& operator>>(istream& lineIn, Contact& newContact) {
      string tempName, tempID, emptyLine;
      if (getline(lineIn, tempID) && getline(lineIn, tempName) && getline(lineIn, emptyLine)) {
          newContact.setID(stoi(tempID));
          newContact.setName(tempName);
      }
      return lineIn;
  }

我想最后的空行并不重要。在这种情况下,您可以将最后一个 getline 移出 if 语句。

为了额外的安全性,您应该检查它tempID是否为整数形式,如果不是,则在流上设置故障位。


推荐阅读