【发布时间】:2018-09-19 11:17:55
【问题描述】:
我编写了这个小程序来从 txt 文件中读取Orders:
struct Date
{
int year;
int month;
int day;
};
istream& operator>>(istream& is, Date& d)
{
int dd, m, y;
char slash1, slash2;
is >> dd >> slash1 >> m >> slash2 >> y;
d.day = dd;
d.month = m;
d.year = y;
return is;
}
class Purchase
{
public:
string product_name;
double unit_price;
int count;
};
istream& operator>>(istream& is, Purchase& p)
{
string pd;
double price;
int cnt;
is >> pd >> price >> cnt;
if (!is)
{
is.unget();
is.clear(ios_base::failbit);
return is;
}
p.product_name = pd;
p.unit_price = price;
p.count = cnt;
return is;
}
struct Address
{
string add;
};
istream& operator>>(istream& is, Address& a)
{
string s;
string aa;
while (true)
{
is >> aa;
s = s + aa + ' ';
if (s[s.length() - 2] == '.')break;
}
a.add = s;
return is;
}
class Order
{
public:
string name;
Address address;
Date dt;
vector<Purchase>purch;
};
istream& operator>>(istream& is, Order& o)
{
string nm;
Address aa;
Date dd;
is >> nm>> aa >> dd;
if (!is)
{
is.unget();
is.clear(ios_base::failbit);
return is;
}
o.name = nm;
o.address.add = aa.add;
o.dt.day = dd.day;
o.dt.month = dd.month;
o.dt.year = dd.year;
for (Purchase pp; is >> pp;)
{
o.purch.push_back(pp);
}
return is;
}
文本文件格式如下:
John
3, Apple Street, Lagos.
11/3/2018
Soap 100 2
Cream 250 1
Cheese 50 6
Matthew
10, Orange Street, Milan.
10/1/2018
Tissue 50 2
Cookies 10 5
Shirts 500 2
Pen 35 1
在main函数中测试这个程序时:
int main()
{
cout << "Enter input file name: ";
string input_file;
cin >> input_file;
ifstream ifs{ input_file };
vector<Order>ord;
while (true)
{
Order g;
if (!ifs)break;
ifs >> g;
ord.push_back(g);
}
cout << ord[0].name << endl;
cout << ord[0].address.add << endl;
cout << ord[0].dt.year << endl;
cout << ord[0].purch[0].count << endl;
cout << endl;
}
我发现它只将Order 的第一个实例读入ord 向量。 ifstream ifs 在第二次尝试读取新的Order 时失败并爆发。所以在上面的示例文件中,我只能成功读取 John 的订单。现在我被困住了,我需要帮助。谢谢。
【问题讨论】:
-
您只打印一份订单(即
ord[0]) -
@codekaizer 我就这样离开了,因为这是唯一有效的下标...当我打印
ord[1]时,它说向量下标超出范围@ -
for (Purchase pp; is >> pp;)循环在消耗整个文件之前不会终止。 -
@IgorTandetnik 我也试过这个循环来阅读
Purchase:while (true) { Purchase pp; if (!(is >> pp))break; o.purch.push_back(pp); } -
(is >> pp)只会在eof上变为false(在布尔上下文中),因为您在返回之前明确清除了failbit。支票的任何洗牌都不会改变这一事实。
标签: c++ c++11 file-io io iostream