Sales_data.h
#pragma once
#include <iostream>
#include <string>
using namespace std;
class Sales_data {
public:
Sales_data() = default; //默认构造函数
//带一个参数的构造函数
Sales_data(const string& book) : bookNo(book),
units_sold(0),sellingprice(0),saleprice(0),
discount(0){ }
/*
//委托构造函数
Sales_data(const string& book, unsigned num,
double sellp,double salep) :bookNo(book),
units_sold(num),sellingprice(sellp)
,saleprice(salep) {
if (sellingprice)
discount = saleprice / sellingprice;
cout << "该构造函数接受书号、销售量、原价、实际售价四个信息" << endl;
}
//委托构造函数
Sales_data() :Sales_data("", 0, 0, 0) {
cout << "该构造函数无须接受任何信息" << endl;
}
//委托构造函数
Sales_data(const string& book) :Sales_data(book, 0, 0, 0) {
cout << "该构造函数接受书号信息" << endl;
}
//委托构造函数
Sales_data(istream& is) :Sales_data() {
read(is, *this);
cout << "该构造函数接受用户输入的信息" << endl;
}
*/
/*
Sales_data(const string& book, unsigned sold, double sell,
double sale) :bookNo(book), units_sold(sold),
sellingprice(sell), saleprice(sale) {
if (sellingprice) {
discount = saleprice / sellingprice;
}
cout << "此构造函数接受4个参数" << endl;
}
Sales_data(const string& book) :
Sales_data(book, 0, 0, 0) {
cout << "此构造函数接受书号信息" << endl;
}
Sales_data() :Sales_data("", 0, 0, 0) {
cout << "此构造函数接受0个参数" << endl;
}
Sales_data(istream& is):Sales_data() {
read(is, *this);
cout << "此构造函数接受用户输入信息" << endl;
}
*/
//自定义的重载构造函数
/*Sales_data(const string& book, const unsigned num,
const double sellp, const double salep);*/
//带一个(ifstream流引用)参数的构造函数
Sales_data(istream& is) { is >> *this; };
Sales_data& operator += (const Sales_data&);
Sales_data& combine(const Sales_data& rhs);
std::string isbn() const { return bookNo; }
/*------------------------------------------------------------
---------------------------------------------------------------*/
// 友元函数
friend std::istream& operator >> (std::istream&, Sales_data&);
// 友元函数
friend std::ostream& operator << (std::ostream&, const Sales_data&);
// 友元函数
//friend bool operator < (const Sales_data&, const Sales_data&);
// 友元函数
friend bool operator == (const Sales_data&, const Sales_data&);
friend istream& read(istream&, Sales_data&);
friend Sales_data Add(const Sales_data& lhs,
const Sales_data& rhs);
friend ostream& print(ostream&, const Sales_data&);
//隐式内联,把avg_price函数定义在Sales_data类的内部
/*double avg_price()const {
if (units_sold) {
return revenue / units_sold;
}
else {
return 0;
}
}*/
//double avg_price()const;
private:
string bookNo;//书籍编号,隐式初始化为空串
unsigned units_sold = 0;// 销售量,显式初始化为0
double sellingprice = 0.0;// 原始价格,显式初始化为 0.0
double saleprice = 0.0;//实售价格,显式初始化为0.0
double discount = 0.0;// 折扣,显式初始化为 0.0
};
//显示内联 把avg_price函数定义在Sales_data类的外部,并且指定inline
//inline double Sales_data::avg_price()const {
//
// if (units_sold) {
// return revenue / units_sold;
// }
// else {
// return 0;
// }
//
//}
inline bool compareIsbn(const Sales_data& lhs,
const Sales_data& rhs)
{
return lhs.isbn() == rhs.isbn();
}
Sales_data operator + (const Sales_data&,
const Sales_data&);
inline bool operator == (const Sales_data& lhs,
const Sales_data& rhs) {
return lhs.units_sold == rhs.units_sold &&
lhs.sellingprice == rhs.sellingprice &&
lhs.saleprice == rhs.saleprice &&
lhs.isbn() == rhs.isbn();
}
inline bool operator != (const Sales_data& lhs,
const Sales_data& rhs) {
return !(lhs == rhs);// 基于运算符==给出!=的定义
}
Sales_data& Sales_data::operator += (const Sales_data& rhs) {
units_sold += rhs.units_sold; //units_sold = units_sold + rhs.units_sold
saleprice = (rhs.saleprice * rhs.units_sold + saleprice * units_sold)
/ (rhs.units_sold + units_sold);
if (sellingprice != 0)
discount = saleprice / sellingprice;
return *this;
}
Sales_data& Sales_data::combine(const Sales_data& rhs)
{
units_sold += rhs.units_sold;
saleprice = (rhs.saleprice * rhs.units_sold + saleprice * units_sold) /
(rhs.units_sold + units_sold);
if (sellingprice != 0)
discount = saleprice / sellingprice;
return *this;
}
Sales_data Add(const Sales_data& lhs,
const Sales_data& rhs)
{
Sales_data sum = lhs;
sum.combine(rhs);
return sum;
}
Sales_data operator + (const Sales_data& lhs,
const Sales_data& rhs) {
Sales_data ret(lhs); //把 lhs 的内容拷贝到临时变量 ret 中,这种做法便于运算
ret += rhs;// 把 rhs 的内容加入其中
return ret;// 返回 ret
}
std::istream& operator>>(std::istream& in, Sales_data& s) {
in >> s.bookNo >> s.units_sold >> s.sellingprice >> s.saleprice;
if (in && s.sellingprice != 0)
s.discount = s.saleprice / s.sellingprice;
else
s = Sales_data();//输入错误,重置输入的数据
return in;
}
istream& read(std::istream& in, Sales_data& s)
{
in >> s.bookNo >> s.units_sold >> s.sellingprice >> s.saleprice;
if (in && s.sellingprice != 0)
s.discount = s.saleprice / s.sellingprice;
else
s = Sales_data();//输入错误,重置输入的数据
return in;
}
std::ostream& operator << (std::ostream& out,
const Sales_data& s) {
out << "图书编号:" << s.isbn() << " " << "销售量:" << s.units_sold << " "
<< "原始价格:" << s.sellingprice << " " << "实售价格:" << s.saleprice << " " << "折扣:" << s.discount;
return out;
}
inline std::ostream& print(std::ostream& out, const Sales_data& s)
{
out << "图书编号:" << s.isbn() << " " << "销售量:" << s.units_sold << " "
<< "原始价格:" << s.sellingprice << " " << "实售价格:" << s.saleprice << " " << "折扣:" << s.discount << "\n";
return out;
}
/*
Sales_data::Sales_data(const string& book, const unsigned num,
const double sellp, const double salep) {
bookNo = book;
units_sold = num;
sellingprice = sellp;
saleprice = salep;
}
*/
main.cpp
#include <iostream>
#include <fstream>
#include "Sales_data.h"
using namespace std;
/*
练习8.6:重写7.1.1节的书店程序(第229页),
从一个文件中读取交易记录。
将文件名作为一个参数传递给main (参见6.2.5节,第196页)。
*/
int main(int argc, char* argv[]) {
if (argc != 2) {
cerr << "请给出文件名" << endl;
return -1;
}
ifstream in(argv[1]);
if (!in) {
cerr << "无法打开输入文件" << endl;
return -1;
}
Sales_data total;
if (read(in, total)) {
Sales_data trans;
while (read(in, trans)) {
if (total.isbn() == trans.isbn())
total.combine(trans);
else {
print(cout, total) << endl;
total = trans;
}
}
print(cout, total) << endl;
}
else {
cerr << "没有数据" << endl;
}
system("pause");
return 0;
}
1. 准备前期工作 首先把要读取的文件放在当前.cpp同目录下面,我的是data.txt
2. 文件格式如图下所示
3. VS从命令行获取参数的设置方法
(1)鼠标右键->属性
(2)参照下图设置命令行