簡體   English   中英

文件循環和讀入映射問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM