c++新手一枚,最近在学习c++ Primer。练习7.13的源代码很有意思。
众所周知,在用户敲击回车键后,cin会读取缓冲区的输入。
比如你要读5个int,在你输入5个int数字之后敲回车,cin在读完五个数字后,回车键却会保留在缓冲区中。
有时我们可以利用这最后一个回车键,作为判断是否有下一次输入的依据。
头文件如下:
Sales_data.h #pragma once #include<string> #include<iostream> using namespace std; struct Sales_data { istream& read(istream &is, Sales_data &data); Sales_data() = default; Sales_data(const string &s) :bookNo(s) {} Sales_data(const string &s, unsigned us, double co, double pri); Sales_data(istream &is) {read(is, *this);} string isbn()const { return bookNo; } Sales_data &combine(const Sales_data &rhs); string bookNo; unsigned units_sold = 0; double cost = 0.0, price = 0.0; double revenue = 0.0, profit = 0.0; }; istream& Sales_data::read(istream &is, Sales_data &data) { cout << "请输入书名号、销售量、成本、单价:" << endl; is >> data.bookNo >> data.units_sold >> data.cost >> data.price; data.revenue = data.units_sold*data.price; data.profit = data.revenue - data.units_sold*data.cost; return is; } ostream& print(ostream &os, const Sales_data &data) { os << data.bookNo << " " << data.units_sold << " " << data.revenue << " " << data.profit << " "; return os; } Sales_data &Sales_data::combine(const Sales_data &rhs) { units_sold += rhs.units_sold; revenue += rhs.revenue; profit += rhs.profit; return *this; } Sales_data::Sales_data(const string &s, unsigned us, double co, double pri) :bookNo(s), units_sold(us), cost(co), price(pri) { revenue = us*pri; profit = us*(pri - co); }main函数如下:
#include"Sales_data.h" int main() { Sales_data data1(cin);//本次输入后,回车键留存在缓冲区中,作为while的判断依据 if (!data1.isbn().empty()) { while (cin)//cin读取了回车键,继续循环 { Sales_data data2(cin); if (data1.isbn() == data2.isbn()) { data1.combine(data2); } else { print(cout, data1); data1 = data2; } }//在输入~z结束循环时,while开头的cin会再次读入回车键并判断成功,此时data2会用默认构造函数初始化,导致data1、data2的isbn编号不匹配,print函数输出最后一条消息后,while开头的cin才会读取到非法输入,结束循环。 } else cerr << "No data" << endl; system("pause"); return 0; }