[英]Problem with file loop and reading into map
从文件读取时的while循环不会中断。 我不确定是什么问题。 如果您需要更多信息,请询问。
码:
#include <string>
#include <map>
#include <fstream>
#include <iostream>
#include <iterator>
using namespace std;
class Customer {
public:
string name;
string address;
Customer() {}
};
class Purchase {
public:
string product_name;
double unit_price;
int count;
Purchase() {}
Purchase(string pn, double up, int c) :product_name(pn), unit_price(up), count(c) {}
};
// Function Object for comparison in map container
struct Cmp_name {
bool operator()(const Customer& first, const Customer& second)
{ return first.name < second.name; }
};
// ostream overloads
ostream& operator<<(ostream& out, const Customer& c)
{
out << c.name << '\n'
<< c.address << '\n';
return out;
}
ostream& operator<<(ostream& out, const Purchase& p)
{
out << p.product_name << '\n'
<< p.unit_price << '\n'
<< p.count << '\n';
return out;
}
istream& operator>>(istream& in, Customer& c)
{
getline(in, c.name);
getline(in, c.address);
return in;
}
istream& operator>>(istream& in, Purchase& p)
{
getline(in, p.product_name);
in >> p.unit_price >> p.count;
return in;
}
int main()
{
cout << "Enter file to read orders from: \n";
string file;
cin >> file;
ifstream is(file.c_str());
if (!is) cerr << "File doesn't exist.\n";
multimap<Customer, Purchase, Cmp_name> orders;
while (!is.eof()) {
Customer c;
Purchase p;
is >> c;
is >> p;
orders.insert(make_pair(c,p));
}
for (multimap<Customer, Purchase, Cmp_name>::iterator it = orders.begin(); it!=orders.end(); ++it)
cout << it->first << it->second << "\n\n";
}
对于您的客户/购买ostream插入器,声明第二个参数const&而不是非const&。 例如:
ostream& operator<<(ostream& out, Customer const& c)
这是必须的,因为即使您使用的是非常量迭代器,映射中的键也是不可变的(修改键将使映射实现使用的任何树排序或散列操作均无效。
最好检查每个istream提取操作是否成功,并在第一次失败时退出循环。 您的“ is.eof()”将不会读取任何额外的字符(例如,空格),因此它可能会在文件的语义结尾声明“!eof()”。
就像是:
for(;;) {
Customer c;
Purchase p;
if (!getline(is, c.name)) break;
if (!getline(is, c.address) break;
if (!getline(is, p.product_name) break;
if (!(is >> p.unit_price >> p.count)) break;
orders.insert(make_pair(c,p));
}
由于所有这些都返回原始istream,因此与“ if(!is)中断;”相同。 在每次尝试输入之后。
您还可以通过定义“客户”和“购买”的提取器来简化一些事情,例如
istream&运营商>>(istream&i,Customer&c)
未能读取Customer会让您分手(如果eof阻止读取成功,则istream会评估为false)。
显然,您可以使某些失败的输入点“确定为正确”,并在所有其他情况下给出特定的错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.