├── .gitignore ├── Cpp_Primer_Answer.vcxproj ├── Cpp_Primer_Answer.vcxproj.filters ├── Cpp_Primer_Answer.vcxproj.user ├── README.md ├── ch01 ├── README.md ├── exercise1_1.cpp ├── exercise1_10.cpp ├── exercise1_11.cpp ├── exercise1_16.cpp ├── exercise1_18.cpp ├── exercise1_20.cpp ├── exercise1_21.cpp ├── exercise1_22.cpp ├── exercise1_23.cpp └── exercise1_9.cpp ├── ch02 ├── README.md ├── exercise2_34.cpp ├── exercise2_4.cpp ├── exercise2_42_1.cpp ├── exercise2_42_2.cpp └── exercise2_42_3.cpp ├── ch03 ├── README.md ├── exercise3_10.cpp ├── exercise3_14.cpp ├── exercise3_15.cpp ├── exercise3_16.cpp ├── exercise3_17.cpp ├── exercise3_20.cpp ├── exercise3_21.cpp ├── exercise3_22.cpp ├── exercise3_23.cpp ├── exercise3_24.cpp ├── exercise3_25.cpp ├── exercise3_2_a.cpp ├── exercise3_2_b.cpp ├── exercise3_31.cpp ├── exercise3_32.cpp ├── exercise3_35.cpp ├── exercise3_36.cpp ├── exercise3_39.cpp ├── exercise3_40.cpp ├── exercise3_41.cpp ├── exercise3_42.cpp ├── exercise3_43.cpp ├── exercise3_44.cpp ├── exercise3_45.cpp ├── exercise3_4_a.cpp ├── exercise3_4_b.cpp ├── exercise3_5_a.cpp ├── exercise3_5_b.cpp ├── exercise3_6.cpp ├── exercise3_7.cpp ├── exercise3_8.cpp ├── exercise_3_1_a.cpp └── exercise_3_1_b.cpp ├── ch04 ├── README.md ├── exercise4_21.cpp ├── exercise4_22.cpp └── exercise4_28.cpp ├── ch05 ├── README.md ├── exercise5_10.cpp ├── exercise5_11.cpp ├── exercise5_12.cpp ├── exercise5_14.cpp ├── exercise5_17.cpp ├── exercise5_19.cpp ├── exercise5_20.cpp ├── exercise5_21.cpp ├── exercise5_23.cpp ├── exercise5_24.cpp ├── exercise5_25.cpp ├── exercise5_5.cpp ├── exercise5_6.cpp └── exercise5_9.cpp ├── ch06 ├── Chapter6.h ├── README.md ├── exercise6_10.cpp ├── exercise6_11.cpp ├── exercise6_12.cpp ├── exercise6_17.cpp ├── exercise6_21.cpp ├── exercise6_22.cpp ├── exercise6_23.cpp ├── exercise6_25.cpp ├── exercise6_27.cpp ├── exercise6_3.cpp ├── exercise6_30.cpp ├── exercise6_33.cpp ├── exercise6_4.cpp ├── exercise6_42.cpp ├── exercise6_47.cpp ├── exercise6_51.cpp ├── exercise6_55.cpp ├── fact.cpp └── factMain.cpp ├── ch07 ├── README.md ├── exercise7_1.cpp ├── exercise7_11.cpp ├── exercise7_11.h ├── exercise7_12.h ├── exercise7_13.cpp ├── exercise7_15.h ├── exercise7_2.h ├── exercise7_21.h ├── exercise7_22.h ├── exercise7_23.h ├── exercise7_24.h ├── exercise7_26.h ├── exercise7_27.cpp ├── exercise7_27.h ├── exercise7_3.cpp ├── exercise7_32.h ├── exercise7_4.h ├── exercise7_41.cpp ├── exercise7_41.h ├── exercise7_41_main.cpp ├── exercise7_5.h ├── exercise7_6.h ├── exercise7_7.cpp └── exercise7_9.h ├── ch08 ├── README.md ├── exercise8_10.cpp ├── exercise8_11.cpp ├── exercise8_13.cpp ├── exercise8_2.cpp ├── exercise8_6.cpp ├── exercise8_7.cpp ├── exercise8_8.cpp └── exercise8_9.cpp ├── ch09 ├── README.md ├── exercise9_13.cpp ├── exercise9_18.cpp ├── exercise9_20.cpp ├── exercise9_24.cpp ├── exercise9_27.cpp ├── exercise9_33.cpp ├── exercise9_34.cpp ├── exercise9_38.cpp ├── exercise9_43.cpp ├── exercise9_44.cpp ├── exercise9_45.cpp ├── exercise9_46.cpp ├── exercise9_47.cpp ├── exercise9_49.cpp ├── exercise9_50.cpp ├── exercise9_51.cpp └── exercise9_52.cpp ├── ch10 ├── README.md ├── exercise10_1.cpp ├── exercise10_11.cpp ├── exercise10_12.cpp ├── exercise10_13.cpp ├── exercise10_16.cpp ├── exercise10_17.cpp ├── exercise10_18.cpp ├── exercise10_19.cpp ├── exercise10_2.cpp ├── exercise10_20.cpp ├── exercise10_22.cpp ├── exercise10_24.cpp ├── exercise10_25.cpp ├── exercise10_27.cpp ├── exercise10_28.cpp ├── exercise10_29.cpp ├── exercise10_3.cpp ├── exercise10_30.cpp ├── exercise10_31.cpp ├── exercise10_32.cpp ├── exercise10_33.cpp ├── exercise10_34.cpp ├── exercise10_35.cpp ├── exercise10_36.cpp ├── exercise10_37.cpp ├── exercise10_4.cpp ├── exercise10_42.cpp ├── exercise10_6.cpp ├── exercise10_9.cpp └── exercise7_26.h ├── ch11 ├── README.md ├── exercise11_12.cpp ├── exercise11_14.cpp ├── exercise11_20.cpp ├── exercise11_23.cpp ├── exercise11_3.cpp ├── exercise11_31.cpp ├── exercise11_32.cpp ├── exercise11_33.cpp ├── exercise11_38.cpp ├── exercise11_4.cpp └── exercise11_8.cpp ├── ch12 ├── README.md ├── exercise12_14.cpp ├── exercise12_15.cpp ├── exercise12_16.cpp ├── exercise12_19.h ├── exercise12_2.cpp ├── exercise12_2.h ├── exercise12_20.cpp ├── exercise12_23.cpp ├── exercise12_24.cpp ├── exercise12_26.cpp ├── exercise12_27.cpp ├── exercise12_27.h ├── exercise12_27_main.cpp ├── exercise12_28.cpp ├── exercise12_6.cpp └── exercise12_7.cpp ├── ch13 ├── README.md ├── exercise13_11.h ├── exercise13_13.cpp ├── exercise13_17_1.cpp ├── exercise13_17_2.cpp ├── exercise13_17_3.cpp ├── exercise13_18.h ├── exercise13_19.h ├── exercise13_22.h ├── exercise13_26.h ├── exercise13_27.h ├── exercise13_28.h ├── exercise13_30.h ├── exercise13_31.h ├── exercise13_34.cpp ├── exercise13_34.h ├── exercise13_39.cpp ├── exercise13_39.h ├── exercise13_44.cpp ├── exercise13_44.h ├── exercise13_44_main.cpp ├── exercise13_5.h ├── exercise13_53.cpp ├── exercise13_53.h ├── exercise13_58.cpp └── exercise13_8.h ├── ch14 ├── README.md ├── exercise14_15.cpp ├── exercise14_15.h ├── exercise14_15_main.cpp ├── exercise14_2.cpp ├── exercise14_2.h ├── exercise14_22.cpp ├── exercise14_22.h ├── exercise14_22_main.cpp ├── exercise14_23.cpp ├── exercise14_23.h ├── exercise14_23_main.cpp ├── exercise14_24.cpp ├── exercise14_24.h ├── exercise14_24_main.cpp ├── exercise14_35.cpp ├── exercise14_36.cpp ├── exercise14_37.cpp ├── exercise14_38.cpp ├── exercise14_40.cpp ├── exercise14_43.cpp ├── exercise14_44.cpp ├── exercise14_45.cpp ├── exercise14_45.h ├── exercise14_45_main.cpp ├── exercise14_5.cpp ├── exercise14_5.h ├── exercise14_5_main.cpp ├── exercise14_7.cpp ├── exercise14_7.h └── exercise14_7_main.cpp ├── ch15 ├── Bulk_quote.h ├── Disc_quote.h ├── Limit_quote.h ├── README.md ├── basket.cpp ├── basket.h ├── exercise15_20.cpp ├── exercise15_26.h ├── exercise15_26_2.h ├── exercise15_27.h ├── exercise15_28.cpp ├── exercise15_3.cpp ├── exercise15_3.h ├── exercise15_5.h ├── exercise15_6.cpp ├── exercise15_7.h ├── main.cpp ├── query.h └── query_base.h ├── ch16 ├── README.md ├── blob.h ├── blobptr.h ├── debugDelete.h ├── delete.h ├── screen.h ├── shared_ptr.h ├── unique_ptr.h └── vec.h ├── ch17 └── README.md ├── ch18 └── README.md ├── ch19 └── README.md └── data ├── Sales_item.h ├── Version_test.h ├── books.txt ├── exercise1_17.png ├── exercise1_2.png ├── exercise1_24.png ├── exercise1_7.png ├── exercise2_42.h ├── for_transform.txt ├── letter.txt ├── phonenumbers.txt ├── storyDataFile.txt └── transform_rules.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | 30 | Debug 31 | .gitattributes 32 | Cpp_Primer_Answer.sdf 33 | Cpp_Primer_Answer.opensdf 34 | Cpp_Primer_Answer.v12.suo -------------------------------------------------------------------------------- /Cpp_Primer_Answer.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 头文件 20 | 21 | 22 | 23 | 24 | 源文件 25 | 26 | 27 | 源文件 28 | 29 | 30 | -------------------------------------------------------------------------------- /Cpp_Primer_Answer.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | false 5 | 6 | 7 | hello world 8 | WindowsLocalDebugger 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 《C++ Primer》第五版中文版习题答案 2 | ### 说明: 3 | * 我的这个项目大量参考了[Cpp-Primer](https://github.com/Mooophy/Cpp-Primer),我也有过和原作者的讨论并提交过 pull request。所以不能说是我抄的,而且读书人的事,怎么能算抄呢。。。 4 | * 发现了书中有两处错误的地方,其中一处英文原版书中也有错误。一处在[第9章](https://www.zhihu.com/question/39255704),一处在[第14章](https://www.zhihu.com/question/42262890)。 5 | * 编译器是 Visual Studio 2013 6 | * 建议大家把书换成英文版的,这个项目有很多我当时留下来的错误,可能会误导初学者。所以这也证明了学习一定要使用第一手资料,中文资料的作者并不想制造错误但总是会有疏忽的(2019年5月)。 7 | 8 | #### 下面是目录: 9 | - [第1章 : 开始](ch01/README.md) 10 | - 第 I 部分 : C++基础 11 | - [第2章 : 变量和基本类型](ch02/README.md) 12 | - [第3章 : 字符串、向量和数组](ch03/README.md) 13 | - [第4章 : 表达式](ch04/README.md) 14 | - [第5章 : 语句](ch05/README.md) 15 | - [第6章 : 函数](ch06/README.md) 16 | - [第7章 : 类](ch07/README.md) 17 | - 第 II 部分 : C++标准库 18 | - [第8章 : IO库](ch08/README.md) 19 | - [第9章 : 顺序容器](ch09/README.md) 20 | - [第10章 : 泛型算法](ch10/README.md) 21 | - [第11章 : 关联容器](ch11/README.md) 22 | - [第12章 : 动态内存](ch12/README.md) 23 | - 第 III 部分 : 类设计者的工具 24 | - [第13章 : 拷贝控制](ch13/README.md) 25 | - [第14章 : 重载与类型转换](ch14/README.md) 26 | - [第15章 : 面向对象程序设计](ch15/README.md) 27 | - [第16章 : 模版与泛型编程](ch16/README.md) 28 | - 第 IV 部分 : 高级主题 29 | - [第17章 : 标准库与特殊设施](ch17/README.md) 30 | - [第18章 : 用于大型程序的工具](ch18/README.md) 31 | - [第19章 : 特殊工具与技术](ch19/README.md) 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /ch01/exercise1_1.cpp: -------------------------------------------------------------------------------- 1 | int main() 2 | { 3 | return -1; 4 | } -------------------------------------------------------------------------------- /ch01/exercise1_10.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | int i = 10; 6 | 7 | while (i >= 0) 8 | { 9 | std::cout << i << std::endl; 10 | --i; 11 | } 12 | 13 | return 0; 14 | } -------------------------------------------------------------------------------- /ch01/exercise1_11.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void print_range(int lo, int hi) 4 | { 5 | if (lo > hi) 6 | { 7 | print_range(hi, lo); 8 | return; 9 | } 10 | while (lo <= hi) 11 | { 12 | std::cout << lo << std::endl; 13 | ++lo; 14 | } 15 | } 16 | 17 | int main() 18 | { 19 | int low, high; 20 | std::cout << "please input two numbers : " << std::endl; 21 | std::cin >> low >> high; 22 | 23 | print_range(low, high); 24 | return 0; 25 | } -------------------------------------------------------------------------------- /ch01/exercise1_16.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | int sum = 0, value = 0; 6 | 7 | while (std::cin >> value) 8 | { 9 | sum += value; 10 | } 11 | 12 | std::cout << sum << std::endl; 13 | 14 | return 0; 15 | } -------------------------------------------------------------------------------- /ch01/exercise1_18.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | int currVal = 0, val = 0; 6 | 7 | if (std::cin >> currVal) 8 | { 9 | int cnt = 1; 10 | while (std::cin >> val) 11 | { 12 | if (val == currVal) 13 | { 14 | ++cnt; 15 | } 16 | else 17 | { 18 | std::cout << currVal << " occurs " << cnt << " times" << std::endl; 19 | currVal = val; 20 | cnt = 1; 21 | } 22 | } 23 | std::cout << currVal << " occurs " << cnt << " times" << std::endl; 24 | } 25 | return 0; 26 | } -------------------------------------------------------------------------------- /ch01/exercise1_20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Sales_item.h" 3 | 4 | using std::cin; 5 | using std::cout; 6 | using std::endl; 7 | 8 | int main() 9 | { 10 | for (Sales_item item; cin >> item; cout << item << endl); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /ch01/exercise1_21.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Sales_item.h" 3 | 4 | using namespace std; 5 | 6 | int main() 7 | { 8 | Sales_item item1, item2; 9 | cin >> item1 >> item2; 10 | 11 | if (item1.isbn() == item2.isbn()) 12 | { 13 | cout << item1 + item2 << endl; 14 | } 15 | else 16 | { 17 | cerr << "Different ISBN." << endl; 18 | } 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /ch01/exercise1_22.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Sales_item.h" 3 | 4 | int main() 5 | { 6 | Sales_item total; 7 | if (std::cin >> total) 8 | { 9 | Sales_item trans; 10 | while (std::cin >> trans) 11 | { 12 | if (total.isbn() == trans.isbn()) 13 | total += trans; 14 | else 15 | { 16 | std::cout << total << std::endl; 17 | total = trans; 18 | } 19 | } 20 | std::cout << total << std::endl; 21 | } 22 | else 23 | { 24 | std::cerr << "No data?!" << std::endl; 25 | return -1; 26 | } 27 | 28 | return 0; 29 | } -------------------------------------------------------------------------------- /ch01/exercise1_23.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Sales_item.h" 3 | 4 | int main() 5 | { 6 | Sales_item currItem, valItem; 7 | if (std::cin >> currItem) 8 | { 9 | int cnt = 1; 10 | while (std::cin >> valItem) 11 | { 12 | if (valItem.isbn() == currItem.isbn()) 13 | { 14 | ++cnt; 15 | } 16 | else 17 | { 18 | std::cout << currItem << " occurs " << cnt << " times " << std::endl; 19 | currItem = valItem; 20 | cnt = 1; 21 | } 22 | } 23 | std::cout << currItem << " occurs " << cnt << " times " << std::endl; 24 | } 25 | return 0; 26 | } -------------------------------------------------------------------------------- /ch01/exercise1_9.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | int sum = 0, i = 50; 6 | 7 | while (i <= 100) 8 | { 9 | sum += i; 10 | ++i; 11 | } 12 | 13 | std::cout << sum << std::endl; 14 | 15 | return 0; 16 | } -------------------------------------------------------------------------------- /ch02/exercise2_34.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangmingchuan/Cpp_Primer_Answers/925506ca53f7b2e8501bc8eaaee3dba8c03d9ec2/ch02/exercise2_34.cpp -------------------------------------------------------------------------------- /ch02/exercise2_4.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | unsigned u = 10, u2 = 42; 6 | std::cout << u2 - u << std::endl; // 32 7 | std::cout << u - u2 << std::endl; // 4294967264 8 | int i = 10, i2 = 42; 9 | std::cout << i2 - i << std::endl; // 32 10 | std::cout << i - i2 << std::endl; // -32 11 | std::cout << i - u << std::endl; // 0 12 | std::cout << u - i << std::endl; // 0 13 | 14 | return 0; 15 | } -------------------------------------------------------------------------------- /ch02/exercise2_42_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "exercise2_42.h" 3 | 4 | int main() 5 | { 6 | Sales_data book; 7 | double price; 8 | std::cin >> book.bookNo >> book.units_sold >> price; 9 | book.CalcRevenue(price); 10 | book.Print(); 11 | 12 | return 0; 13 | } -------------------------------------------------------------------------------- /ch02/exercise2_42_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "exercise2_42.h" 3 | 4 | int main() 5 | { 6 | Sales_data book1, book2; 7 | double price1, price2; 8 | std::cin >> book1.bookNo >> book1.units_sold >> price1; 9 | std::cin >> book2.bookNo >> book2.units_sold >> price2; 10 | book1.CalcRevenue(price1); 11 | book2.CalcRevenue(price2); 12 | 13 | if (book1.bookNo == book2.bookNo) 14 | { 15 | book1.AddData(book2); 16 | book1.Print(); 17 | return 0; 18 | } 19 | else 20 | { 21 | std::cerr << "Data must refer to same ISBN" << std::endl; 22 | return -1; 23 | } 24 | } -------------------------------------------------------------------------------- /ch02/exercise2_42_3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "exercise2_42.h" 3 | 4 | int main() 5 | { 6 | Sales_data total; 7 | double totalPrice; 8 | if (std::cin >> total.bookNo >> total.units_sold >> totalPrice) 9 | { 10 | total.CalcRevenue(totalPrice); 11 | Sales_data trans; 12 | double transPrice; 13 | while (std::cin >> trans.bookNo >> trans.units_sold >> transPrice) 14 | { 15 | trans.CalcRevenue(transPrice); 16 | if (total.bookNo == trans.bookNo) 17 | { 18 | total.AddData(trans); 19 | } 20 | else 21 | { 22 | total.Print(); 23 | total.SetData(trans); 24 | } 25 | } 26 | total.Print(); 27 | return 0; 28 | } 29 | else 30 | { 31 | std::cerr << "No data?!" << std::endl; 32 | return -1; 33 | } 34 | } -------------------------------------------------------------------------------- /ch03/exercise3_10.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::string; 6 | using std::cin; 7 | using std::cout; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | string s = "this, is. a :string!"; 13 | string result; 14 | 15 | for (auto x : s) 16 | { 17 | if (!ispunct(x)) 18 | { 19 | result += x; 20 | } 21 | } 22 | 23 | cout << result << endl; 24 | return 0; 25 | } -------------------------------------------------------------------------------- /ch03/exercise3_14.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using std::cin; 7 | using std::cout; 8 | using std::endl; 9 | using std::vector; 10 | 11 | int main() 12 | { 13 | vector v; 14 | int i; 15 | while (cin >> i) 16 | { 17 | v.push_back(i); 18 | } 19 | return 0; 20 | } -------------------------------------------------------------------------------- /ch03/exercise3_15.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using std::cin; 7 | using std::cout; 8 | using std::endl; 9 | using std::vector; 10 | using std::string; 11 | 12 | int main() 13 | { 14 | vector v; 15 | string i; 16 | while (cin >> i) 17 | { 18 | v.push_back(i); 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /ch03/exercise3_16.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using std::cin; 7 | using std::cout; 8 | using std::endl; 9 | using std::vector; 10 | using std::string; 11 | 12 | int main() 13 | { 14 | vector v1; // size:0, no values. 15 | vector v2(10); // size:10, value:0 16 | vector v3(10, 42); // size:10, value:42 17 | vector v4{ 10 }; // size:1, value:10 18 | vector v5{ 10, 42 }; // size:2, value:10, 42 19 | vector v6{ 10 }; // size:10, value:"" 20 | vector v7{ 10, "hi" }; // size:10, value:"hi" 21 | 22 | cout << "v1 size :" << v1.size() << endl; 23 | cout << "v2 size :" << v2.size() << endl; 24 | cout << "v3 size :" << v3.size() << endl; 25 | cout << "v4 size :" << v4.size() << endl; 26 | cout << "v5 size :" << v5.size() << endl; 27 | cout << "v6 size :" << v6.size() << endl; 28 | cout << "v7 size :" << v7.size() << endl; 29 | 30 | cout << "v1 content: "; 31 | for (auto i : v1) 32 | { 33 | cout << i << " , "; 34 | } 35 | cout << endl; 36 | 37 | cout << "v2 content: "; 38 | for (auto i : v2) 39 | { 40 | cout << i << " , "; 41 | } 42 | cout << endl; 43 | 44 | cout << "v3 content: "; 45 | for (auto i : v3) 46 | { 47 | cout << i << " , "; 48 | } 49 | cout << endl; 50 | 51 | cout << "v4 content: "; 52 | for (auto i : v4) 53 | { 54 | cout << i << " , "; 55 | } 56 | cout << endl; 57 | 58 | cout << "v5 content: "; 59 | for (auto i : v5) 60 | { 61 | cout << i << " , "; 62 | } 63 | cout << endl; 64 | 65 | cout << "v6 content: "; 66 | for (auto i : v6) 67 | { 68 | cout << i << " , "; 69 | } 70 | cout << endl; 71 | 72 | cout << "v7 content: "; 73 | for (auto i : v7) 74 | { 75 | cout << i << " , "; 76 | } 77 | cout << endl; 78 | return 0; 79 | } -------------------------------------------------------------------------------- /ch03/exercise3_17.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using std::cin; 7 | using std::cout; 8 | using std::endl; 9 | using std::vector; 10 | using std::string; 11 | 12 | int main() 13 | { 14 | vector v; 15 | string s; 16 | 17 | while (cin >> s) 18 | { 19 | v.push_back(s); 20 | } 21 | 22 | for (auto &str : v) 23 | { 24 | for (auto &c : str) 25 | { 26 | c = toupper(c); 27 | } 28 | } 29 | 30 | for (auto i : v) 31 | { 32 | cout << i << endl; 33 | } 34 | return 0; 35 | } -------------------------------------------------------------------------------- /ch03/exercise3_20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using std::cin; 7 | using std::cout; 8 | using std::endl; 9 | using std::vector; 10 | using std::string; 11 | 12 | int main() 13 | { 14 | vector ivec; 15 | int i; 16 | while (cin >> i) 17 | { 18 | ivec.push_back(i); 19 | } 20 | 21 | for (int i = 0; i < ivec.size() - 1; ++i) 22 | { 23 | cout << ivec[i] + ivec[i + 1] << endl; 24 | } 25 | 26 | //--------------------------------- 27 | cout << "---------------------------------" << endl; 28 | 29 | int m = 0; 30 | int n = ivec.size() - 1; 31 | while (m < n) 32 | { 33 | cout << ivec[m] + ivec[n] << endl; 34 | ++m; 35 | --n; 36 | } 37 | return 0; 38 | } -------------------------------------------------------------------------------- /ch03/exercise3_21.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using std::vector; 7 | using std::string; 8 | using std::cout; 9 | using std::endl; 10 | 11 | void check_and_print(const vector& vec) 12 | { 13 | cout << "size: " << vec.size() << " content: ["; 14 | for (auto it = vec.begin(); it != vec.end(); ++it) 15 | cout << *it << (it != vec.end() - 1 ? "," : ""); 16 | cout << "]\n" << endl; 17 | } 18 | 19 | void check_and_print(const vector& vec) 20 | { 21 | 22 | cout << "size: " << vec.size() << " content: ["; 23 | for (auto it = vec.begin(); it != vec.end(); ++it) 24 | cout << *it << (it != vec.end() - 1 ? "," : ""); 25 | cout << "]\n" << endl; 26 | } 27 | 28 | int main() 29 | { 30 | vector v1; 31 | vector v2(10); 32 | vector v3(10, 42); 33 | vector v4{ 10 }; 34 | vector v5{ 10, 42 }; 35 | vector v6{ 10 }; 36 | vector v7{ 10, "hi" }; 37 | 38 | check_and_print(v1); 39 | check_and_print(v2); 40 | check_and_print(v3); 41 | check_and_print(v4); 42 | check_and_print(v5); 43 | check_and_print(v6); 44 | check_and_print(v7); 45 | 46 | return 0; 47 | } -------------------------------------------------------------------------------- /ch03/exercise3_22.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | int main() 9 | { 10 | vector text; 11 | text.push_back("aaaaaaaaaa aaaaaaaaa aaaaaa"); 12 | text.push_back(""); 13 | text.push_back("bbbbbbbbbbbbbb bbbbbbbbbbb bbbbbbbbbbbbb"); 14 | 15 | for (auto it = text.begin(); it != text.end() && !it->empty(); ++it) 16 | { 17 | for (auto &c : *it) 18 | { 19 | if (isalpha(c)) c = toupper(c); 20 | } 21 | } 22 | 23 | for (auto it : text) 24 | { 25 | cout << it << endl; 26 | } 27 | return 0; 28 | } -------------------------------------------------------------------------------- /ch03/exercise3_23.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() 7 | { 8 | vector ivec(10, 42); 9 | 10 | for (auto &it : ivec) 11 | { 12 | it = it * 2; 13 | cout << it << endl; 14 | } 15 | 16 | return 0; 17 | } -------------------------------------------------------------------------------- /ch03/exercise3_24.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using std::cin; 7 | using std::cout; 8 | using std::endl; 9 | using std::vector; 10 | using std::string; 11 | 12 | int main() 13 | { 14 | vector ivec; 15 | int i; 16 | while (cin >> i) 17 | { 18 | ivec.push_back(i); 19 | } 20 | 21 | for (auto it = ivec.begin(); it != ivec.end() - 1; ++it) 22 | { 23 | cout << *it + *(it + 1) << endl; 24 | } 25 | 26 | //--------------------------------- 27 | cout << "---------------------------------" << endl; 28 | 29 | auto it1 = ivec.begin(); 30 | auto it2 = ivec.end() - 1; 31 | while (it1 < it2) 32 | { 33 | cout << *it1 + *it2 << endl; 34 | ++it1; 35 | --it2; 36 | } 37 | return 0; 38 | } -------------------------------------------------------------------------------- /ch03/exercise3_25.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::vector; using std::cout; using std::cin; using std::endl; 5 | 6 | int main() 7 | { 8 | vector scores(11, 0); 9 | unsigned grade; 10 | while (cin >> grade) 11 | { 12 | if (grade <= 100) 13 | ++*(scores.begin() + grade / 10); 14 | } 15 | 16 | for (auto s : scores) 17 | cout << s << " "; 18 | cout << endl; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /ch03/exercise3_2_a.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::string; 5 | using std::cin; 6 | using std::cout; 7 | using std::endl; 8 | using std::getline; 9 | 10 | int main() 11 | { 12 | string s; 13 | while (getline(cin,s)) 14 | { 15 | cout << s << endl; 16 | } 17 | return 0; 18 | } -------------------------------------------------------------------------------- /ch03/exercise3_2_b.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::string; 5 | using std::cin; 6 | using std::cout; 7 | using std::endl; 8 | 9 | int main() 10 | { 11 | string s; 12 | while (cin >> s) 13 | { 14 | cout << s << endl; 15 | } 16 | return 0; 17 | } -------------------------------------------------------------------------------- /ch03/exercise3_31.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 6 | 7 | return 0; 8 | } -------------------------------------------------------------------------------- /ch03/exercise3_32.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::cout; using std::endl; using std::vector; 4 | 5 | int main() 6 | { 7 | // array 8 | int arr[10]; 9 | for (int i = 0; i < 10; ++i) arr[i] = i; 10 | int arr2[10]; 11 | for (int i = 0; i < 10; ++i) arr2[i] = arr[i]; 12 | 13 | // vector 14 | vector v(10); 15 | for (int i = 0; i != 10; ++i) v[i] = arr[i]; 16 | vector v2(v); 17 | for (auto i : v2) cout << i << " "; 18 | cout << endl; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /ch03/exercise3_35.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::cout; 4 | using std::endl; 5 | 6 | int main() 7 | { 8 | const int size = 10; 9 | int arr[size]; 10 | for (auto ptr = arr; ptr != arr + size; ++ptr) *ptr = 0; 11 | 12 | for (auto i : arr) cout << i << " "; 13 | cout << endl; 14 | 15 | return 0; 16 | } -------------------------------------------------------------------------------- /ch03/exercise3_36.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | bool compare(int* const pb1, int* const pe1, int* const pb2, int* const pe2) 8 | { 9 | if ((pe1 - pb1) != (pe2 - pb2)) 10 | return false; 11 | else 12 | { 13 | for (int* i = pb1, *j = pb2; (i != pe1) && (j != pe2); ++i, ++j) 14 | if (*i != *j) return false; 15 | } 16 | 17 | return true; 18 | } 19 | 20 | int main() 21 | { 22 | int arr1[3] = { 0, 1, 2 }; 23 | int arr2[3] = { 0, 2, 4 }; 24 | 25 | if (compare(begin(arr1), end(arr1), begin(arr2), end(arr2))) 26 | cout << "The two arrays are equal." << endl; 27 | else 28 | cout << "The two arrays are not equal." << endl; 29 | 30 | cout << "==========" << endl; 31 | 32 | vector vec1 = { 0, 1, 2 }; 33 | vector vec2 = { 0, 1, 2 }; 34 | 35 | if (vec1 == vec2) 36 | cout << "The two vectors are equal." << endl; 37 | else 38 | cout << "The two vectors are not equal." << endl; 39 | 40 | return 0; 41 | } -------------------------------------------------------------------------------- /ch03/exercise3_39.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using std::cout; using std::endl; using std::string; 5 | 6 | int main() 7 | { 8 | string s1("aaaaaaaaaa"), s2("bbbbbbbbbb"); 9 | if (s1 == s2) 10 | cout << "same string." << endl; 11 | else if (s1 > s2) 12 | cout << "aaaaaaaaaa > bbbbbbbbbb" << endl; 13 | else 14 | cout << "aaaaaaaaaa < bbbbbbbbbb" << endl; 15 | 16 | cout << "=========" << endl; 17 | 18 | const char* cs1 = "aaaaaaaaaa"; 19 | const char* cs2 = "bbbbbbbbbb"; 20 | auto result = strcmp(cs1, cs2); 21 | if (result == 0) 22 | cout << "same string." << endl; 23 | else if (result < 0) 24 | cout << "aaaaaaaaaa < bbbbbbbbbb" << endl; 25 | else 26 | cout << "aaaaaaaaaa > bbbbbbbbbb" << endl; 27 | 28 | return 0; 29 | } -------------------------------------------------------------------------------- /ch03/exercise3_40.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | const char cstr1[] = "Hello"; 5 | const char cstr2[] = "world!"; 6 | 7 | int main() 8 | { 9 | char cstr3[100]; 10 | 11 | strcpy_s(cstr3, cstr1); 12 | strcat_s(cstr3, " "); 13 | strcat_s(cstr3, cstr2); 14 | 15 | std::cout << cstr3 << std::endl; 16 | } -------------------------------------------------------------------------------- /ch03/exercise3_41.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() 7 | { 8 | int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 9 | vector v(begin(arr), end(arr)); 10 | 11 | for (auto i : v) cout << i << " "; 12 | cout << endl; 13 | 14 | return 0; 15 | } -------------------------------------------------------------------------------- /ch03/exercise3_42.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() 7 | { 8 | vector v{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 9 | int arr[10]; 10 | for (int i = 0; i != v.size(); ++i) 11 | arr[i] = v[i]; 12 | 13 | for (auto i : arr) cout << i << " "; 14 | cout << endl; 15 | 16 | return 0; 17 | } -------------------------------------------------------------------------------- /ch03/exercise3_43.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::cout; 4 | using std::endl; 5 | 6 | int main() 7 | { 8 | int arr[3][4] = 9 | { 10 | { 0, 1, 2, 3 }, 11 | { 4, 5, 6, 7 }, 12 | { 8, 9, 10, 11 } 13 | }; 14 | 15 | // range for 16 | for (const int(&row)[4] : arr) 17 | for (int col : row) cout << col << " "; 18 | 19 | cout << endl; 20 | 21 | // for loop 22 | for (size_t i = 0; i != 3; ++i) 23 | for (size_t j = 0; j != 4; ++j) cout << arr[i][j] << " "; 24 | 25 | cout << endl; 26 | 27 | // using pointers. 28 | for (int(*row)[4] = arr; row != arr + 3; ++row) 29 | for (int *col = *row; col != *row + 4; ++col) cout << *col << " "; 30 | 31 | cout << endl; 32 | 33 | return 0; 34 | } -------------------------------------------------------------------------------- /ch03/exercise3_44.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::cout; 4 | using std::endl; 5 | 6 | int main() 7 | { 8 | int ia[3][4] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; 9 | 10 | using int_array = int[4]; 11 | 12 | for (int_array& p : ia) 13 | for (int q : p) 14 | cout << q << " "; 15 | cout << endl; 16 | 17 | for (size_t i = 0; i != 3; ++i) 18 | for (size_t j = 0; j != 4; ++j) 19 | cout << ia[i][j] << " "; 20 | cout << endl; 21 | 22 | for (int_array* p = ia; p != ia + 3; ++p) 23 | for (int *q = *p; q != *p + 4; ++q) 24 | cout << *q << " "; 25 | cout << endl; 26 | 27 | return 0; 28 | } -------------------------------------------------------------------------------- /ch03/exercise3_45.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::cout; 4 | using std::endl; 5 | 6 | int main() 7 | { 8 | int ia[3][4] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; 9 | 10 | for (auto& p : ia) 11 | for (auto q : p) 12 | cout << q << " "; 13 | cout << endl; 14 | 15 | for (auto i = 0; i != 3; ++i) 16 | for (auto j = 0; j != 4; ++j) 17 | cout << ia[i][j] << " "; 18 | cout << endl; 19 | 20 | for (auto p = ia; p != ia + 3; ++p) 21 | for (auto q = *p; q != *p + 4; ++q) 22 | cout << *q << " "; 23 | cout << endl; 24 | 25 | return 0; 26 | } -------------------------------------------------------------------------------- /ch03/exercise3_4_a.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::string; 4 | using std::cin; 5 | using std::cout; 6 | using std::endl; 7 | 8 | int main() 9 | { 10 | string str1, str2; 11 | while (cin >> str1 >> str2) 12 | { 13 | if (str1 == str2) 14 | cout << "The two strings are equal." << endl; 15 | else 16 | cout << "The larger string is " << ((str1 > str2) ? str1 : str2); 17 | } 18 | 19 | return 0; 20 | } -------------------------------------------------------------------------------- /ch03/exercise3_4_b.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::string; 4 | using std::cin; 5 | using std::cout; 6 | using std::endl; 7 | 8 | int main() 9 | { 10 | string str1, str2; 11 | while (cin >> str1 >> str2) 12 | { 13 | if (str1.size() == str2.size()) 14 | cout << "The two strings have the same length." << endl; 15 | else 16 | cout << "The longer string is " << ((str1.size() > str2.size()) ? str1 : str2) << endl; 17 | } 18 | 19 | return 0; 20 | } -------------------------------------------------------------------------------- /ch03/exercise3_5_a.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::string; 5 | using std::cin; 6 | using std::cout; 7 | using std::endl; 8 | 9 | int main() 10 | { 11 | string result, s; 12 | while (cin >> s) 13 | { 14 | result += s; 15 | } 16 | cout << result << endl; 17 | 18 | return 0; 19 | } -------------------------------------------------------------------------------- /ch03/exercise3_5_b.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::string; 5 | using std::cin; 6 | using std::cout; 7 | using std::endl; 8 | 9 | int main() 10 | { 11 | string result, s; 12 | while (cin >> s) 13 | { 14 | result += s + " "; 15 | } 16 | cout << result << endl; 17 | 18 | return 0; 19 | } -------------------------------------------------------------------------------- /ch03/exercise3_6.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::string; 6 | using std::cin; 7 | using std::cout; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | string s = "this is a string"; 13 | 14 | for (auto &x : s) 15 | { 16 | x = 'X'; 17 | } 18 | 19 | cout << s << endl; 20 | return 0; 21 | } -------------------------------------------------------------------------------- /ch03/exercise3_7.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::string; 6 | using std::cin; 7 | using std::cout; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | string s = "this is a string"; 13 | 14 | for (char x : s) 15 | { 16 | x = 'X'; 17 | } 18 | 19 | cout << s << endl; 20 | return 0; 21 | } -------------------------------------------------------------------------------- /ch03/exercise3_8.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::string; 6 | using std::cin; 7 | using std::cout; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | string s = "this is a string"; 13 | 14 | decltype(s.size()) i = 0; 15 | while (i != s.size()) 16 | { 17 | s[i] = 'X'; 18 | ++i; 19 | } 20 | cout << s << endl; 21 | for (i = 0; i != s.size(); ++i) 22 | { 23 | s[i] = 'Y'; 24 | } 25 | cout << s << endl; 26 | return 0; 27 | } -------------------------------------------------------------------------------- /ch03/exercise_3_1_a.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::cin; 4 | using std::cout; 5 | using std::endl; 6 | 7 | int main() 8 | { 9 | int sum = 0; 10 | for (int val = 1; val <= 10; ++val) sum += val; 11 | 12 | cout << "Sum of 1 to 10 inclusive is " << sum << endl; 13 | 14 | return 0; 15 | } -------------------------------------------------------------------------------- /ch03/exercise_3_1_b.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "exercise2_42.h" 4 | 5 | using std::cin; 6 | using std::cout; 7 | using std::endl; 8 | using std::cerr; 9 | 10 | int main() 11 | { 12 | Sales_data data1, data2; 13 | 14 | double price = 0; 15 | 16 | cin >> data1.bookNo >> data1.units_sold >> price; 17 | 18 | data1.revenue = data1.units_sold * price; 19 | 20 | cin >> data2.bookNo >> data2.units_sold >> price; 21 | data2.revenue = data2.units_sold * price; 22 | 23 | if (data1.bookNo == data2.bookNo) 24 | { 25 | unsigned totalCnt = data1.units_sold + data2.units_sold; 26 | double totalRevenue = data1.revenue + data2.revenue; 27 | 28 | cout << data1.bookNo << " " << totalCnt 29 | << " " << totalRevenue << " "; 30 | if (totalCnt != 0) 31 | cout << totalRevenue / totalCnt << endl; 32 | else 33 | cout << "(no sales)" << endl; 34 | 35 | return 0; 36 | } 37 | else 38 | { 39 | cerr << "Data must refer to the same ISBN" << endl; 40 | return -1; 41 | } 42 | } -------------------------------------------------------------------------------- /ch04/exercise4_21.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::cout; 5 | using std::endl; 6 | using std::vector; 7 | 8 | int main() 9 | { 10 | vector ivec{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 11 | 12 | for (auto i : ivec) 13 | { 14 | cout << ((i & 0x1) ? i * 2 : i) << " "; 15 | } 16 | cout << endl; 17 | 18 | return 0; 19 | } -------------------------------------------------------------------------------- /ch04/exercise4_22.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::cout; using std::cin; using std::endl; 3 | 4 | int main() 5 | { 6 | for (unsigned g; cin >> g;) 7 | { 8 | auto result = g > 90 ? "high pass" : g < 60 ? "fail" : g < 75 ? "low pass" : "pass"; 9 | cout << result << endl; 10 | 11 | // ------------------------- 12 | if (g > 90) cout << "high pass"; 13 | else if (g < 60) cout << "fail"; 14 | else if (g < 75) cout << "low pass"; 15 | else cout << "pass"; 16 | cout << endl; 17 | } 18 | 19 | return 0; 20 | } -------------------------------------------------------------------------------- /ch04/exercise4_28.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | cout << "bool:\t\t" << sizeof(bool) << " bytes" << endl << endl; 8 | 9 | cout << "char:\t\t" << sizeof(char) << " bytes" << endl; 10 | cout << "wchar_t:\t" << sizeof(wchar_t) << " bytes" << endl; 11 | cout << "char16_t:\t" << sizeof(char16_t) << " bytes" << endl; 12 | cout << "char32_t:\t" << sizeof(char32_t) << " bytes" << endl << endl; 13 | 14 | cout << "short:\t\t" << sizeof(short) << " bytes" << endl; 15 | cout << "int:\t\t" << sizeof(int) << " bytes" << endl; 16 | cout << "long:\t\t" << sizeof(long) << " bytes" << endl; 17 | cout << "long long:\t" << sizeof(long long) << " bytes" << endl << endl; 18 | 19 | cout << "float:\t\t" << sizeof(float) << " bytes" << endl; 20 | cout << "double:\t\t" << sizeof(double) << " bytes" << endl; 21 | cout << "long double:\t" << sizeof(long double) << " bytes" << endl << endl; 22 | 23 | return 0; 24 | } -------------------------------------------------------------------------------- /ch05/exercise5_10.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::cin; using std::cout; using std::endl; 3 | 4 | int main() 5 | { 6 | unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0; 7 | char ch; 8 | while (cin >> ch) 9 | switch (ch) 10 | { 11 | case 'a': 12 | case 'A': 13 | ++aCnt; 14 | break; 15 | case 'e': 16 | case 'E': 17 | ++eCnt; 18 | break; 19 | case 'i': 20 | case 'I': 21 | ++iCnt; 22 | break; 23 | case 'o': 24 | case 'O': 25 | ++oCnt; 26 | break; 27 | case 'u': 28 | case 'U': 29 | ++uCnt; 30 | break; 31 | } 32 | 33 | cout << "Number of vowel a(A): \t" << aCnt << '\n' 34 | << "Number of vowel e(E): \t" << eCnt << '\n' 35 | << "Number of vowel i(I): \t" << iCnt << '\n' 36 | << "Number of vowel o(O): \t" << oCnt << '\n' 37 | << "Number of vowel u(U): \t" << uCnt << endl; 38 | 39 | return 0; 40 | } -------------------------------------------------------------------------------- /ch05/exercise5_11.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::cin; using std::cout; using std::endl; 4 | 5 | int main() 6 | { 7 | unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0, spaceCnt = 0, tabCnt = 0, newLineCnt = 0; 8 | char ch; 9 | while (cin >> std::noskipws >> ch) 10 | switch (ch) 11 | { 12 | case 'a': 13 | case 'A': 14 | ++aCnt; 15 | break; 16 | case 'e': 17 | case 'E': 18 | ++eCnt; 19 | break; 20 | case 'i': 21 | case 'I': 22 | ++iCnt; 23 | break; 24 | case 'o': 25 | case 'O': 26 | ++oCnt; 27 | break; 28 | case 'u': 29 | case 'U': 30 | ++uCnt; 31 | break; 32 | case ' ': 33 | ++spaceCnt; 34 | break; 35 | case '\t': 36 | ++tabCnt; 37 | break; 38 | case '\n': 39 | ++newLineCnt; 40 | break; 41 | } 42 | 43 | cout << "Number of vowel a(A): \t" << aCnt << '\n' 44 | << "Number of vowel e(E): \t" << eCnt << '\n' 45 | << "Number of vowel i(I): \t" << iCnt << '\n' 46 | << "Number of vowel o(O): \t" << oCnt << '\n' 47 | << "Number of vowel u(U): \t" << uCnt << '\n' 48 | << "Number of space: \t" << spaceCnt << '\n' 49 | << "Number of tab char: \t" << tabCnt << '\n' 50 | << "Number of new line: \t" << newLineCnt << endl; 51 | 52 | return 0; 53 | } -------------------------------------------------------------------------------- /ch05/exercise5_12.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::cin; using std::cout; using std::endl; 4 | 5 | int main() 6 | { 7 | unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0, spaceCnt = 0, tabCnt = 0, newLineCnt = 0, ffCnt = 0, flCnt = 0, fiCnt = 0; 8 | char ch, prech = '\0'; 9 | while (cin >> std::noskipws >> ch) 10 | { 11 | switch (ch) 12 | { 13 | case 'a': 14 | case 'A': 15 | ++aCnt; 16 | break; 17 | case 'e': 18 | case 'E': 19 | ++eCnt; 20 | break; 21 | case 'i': 22 | if (prech == 'f') ++fiCnt; 23 | case 'I': 24 | ++iCnt; 25 | break; 26 | case 'o': 27 | case 'O': 28 | ++oCnt; 29 | break; 30 | case 'u': 31 | case 'U': 32 | ++uCnt; 33 | break; 34 | case ' ': 35 | ++spaceCnt; 36 | break; 37 | case '\t': 38 | ++tabCnt; 39 | break; 40 | case '\n': 41 | ++newLineCnt; 42 | break; 43 | case 'f': 44 | if (prech == 'f') ++ffCnt; 45 | break; 46 | case 'l': 47 | if (prech == 'f') ++flCnt; 48 | break; 49 | } 50 | prech = ch; 51 | } 52 | 53 | cout << "Number of vowel a(A): \t" << aCnt << '\n' 54 | << "Number of vowel e(E): \t" << eCnt << '\n' 55 | << "Number of vowel i(I): \t" << iCnt << '\n' 56 | << "Number of vowel o(O): \t" << oCnt << '\n' 57 | << "Number of vowel u(U): \t" << uCnt << '\n' 58 | << "Number of space: \t" << spaceCnt << '\n' 59 | << "Number of tab char: \t" << tabCnt << '\n' 60 | << "Number of new line: \t" << newLineCnt << '\n' 61 | << "Number of ff: \t" << ffCnt << '\n' 62 | << "Number of fl: \t" << flCnt << '\n' 63 | << "Number of fi: \t" << fiCnt << endl; 64 | 65 | return 0; 66 | } -------------------------------------------------------------------------------- /ch05/exercise5_14.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::cout; using std::cin; using std::endl; using std::string; using std::pair; 5 | 6 | int main() 7 | { 8 | pair max_duplicated; 9 | int count = 0; 10 | for (string str, prestr; cin >> str; prestr = str) 11 | { 12 | if (str == prestr) ++count; 13 | else count = 0; 14 | if (count > max_duplicated.second) max_duplicated = { prestr, count }; 15 | } 16 | 17 | if (max_duplicated.first.empty()) cout << "There's no duplicated string." << endl; 18 | else cout << "the word " << max_duplicated.first << " occurred " << max_duplicated.second + 1 << " times. " << endl; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /ch05/exercise5_17.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::cout; using std::vector; 5 | 6 | bool is_prefix(const vector& lhs, const vector& rhs) 7 | { 8 | if (lhs.size() > rhs.size()) 9 | return is_prefix(rhs, lhs); 10 | for (unsigned i = 0; i != lhs.size(); ++i) 11 | if (lhs[i] != rhs[i]) 12 | return false; 13 | return true; 14 | } 15 | 16 | int main() 17 | { 18 | vector l{ 0, 1, 1, 2 }; 19 | vector r{ 0, 1, 1, 2, 3, 5, 8 }; 20 | cout << (is_prefix(r, l) ? "yes\n" : "no\n"); 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /ch05/exercise5_19.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::cout; using std::cin; using std::endl; using std::string; 5 | 6 | int main() 7 | { 8 | string rsp; 9 | do 10 | { 11 | cout << "Input two strings: "; 12 | string str1, str2; 13 | cin >> str1 >> str2; 14 | cout << (str1 <= str2 ? str1 : str2) 15 | << " is less than the other. " << "\n\n" 16 | << "More? Enter yes or no: "; 17 | cin >> rsp; 18 | } while (tolower(rsp[0]) == 'y'); 19 | return 0; 20 | } -------------------------------------------------------------------------------- /ch05/exercise5_20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::cout; using std::cin; using std::endl; using std::string; 4 | 5 | int main() 6 | { 7 | string read, tmp; 8 | while (cin >> read) 9 | if (read == tmp) break; else tmp = read; 10 | 11 | if (cin.eof()) cout << "no word was repeated." << endl; 12 | else cout << read << " occurs twice in succession." << endl; 13 | 14 | return 0; 15 | } -------------------------------------------------------------------------------- /ch05/exercise5_21.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() 7 | { 8 | string curr, prev; 9 | bool no_twice = true; 10 | while (cin >> curr) 11 | { 12 | if (isupper(curr[0]) && prev == curr) 13 | { 14 | cout << curr << ": occurs twice in succession." << endl; 15 | no_twice = false; 16 | break; 17 | } 18 | prev = curr; 19 | } 20 | 21 | if (no_twice) 22 | cout << "no word was repeated." << endl; 23 | 24 | return 0; 25 | } -------------------------------------------------------------------------------- /ch05/exercise5_23.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::cin; 3 | using std::cout; 4 | using std::endl; 5 | 6 | int main() 7 | { 8 | int i, j; 9 | cin >> i >> j; 10 | cout << i / j << endl; 11 | 12 | return 0; 13 | } -------------------------------------------------------------------------------- /ch05/exercise5_24.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | int i, j; 7 | std::cin >> i >> j; 8 | if (j == 0) 9 | throw std::runtime_error("divisor is 0"); 10 | std::cout << i / j << std::endl; 11 | 12 | return 0; 13 | } -------------------------------------------------------------------------------- /ch05/exercise5_25.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::cin; using std::cout; using std::endl; using std::runtime_error; 4 | 5 | int main(void) 6 | { 7 | int i, j; 8 | cout << "please input tow numbers: " << endl; 9 | while (cin >> i >> j) 10 | { 11 | try 12 | { 13 | if (j == 0) 14 | throw runtime_error("divisor is 0"); 15 | cout << i / j << endl; 16 | } 17 | catch (runtime_error err) 18 | { 19 | cout << err.what() << "\nTry Again? Enter y or n" << endl; 20 | char c; 21 | cin >> c; 22 | if (c != 'y') 23 | break; 24 | } 25 | cout << "please input tow numbers: " << endl; 26 | } 27 | 28 | return 0; 29 | } -------------------------------------------------------------------------------- /ch05/exercise5_5.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using std::vector; using std::string; using std::cout; using std::endl; using std::cin; 5 | 6 | int main() 7 | { 8 | vector scores = { "F", "D", "C", "B", "A", "A++" }; 9 | for (int g; cin >> g;) 10 | { 11 | string letter; 12 | if (g < 60) 13 | { 14 | letter = scores[0]; 15 | } 16 | else 17 | { 18 | letter = scores[(g - 50) / 10]; 19 | if (g != 100) 20 | letter += g % 10 > 7 ? "+" : g % 10 < 3 ? "-" : ""; 21 | cout << letter << endl; 22 | } 23 | } 24 | 25 | return 0; 26 | } -------------------------------------------------------------------------------- /ch05/exercise5_6.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using std::vector; using std::string; using std::cout; using std::endl; using std::cin; 5 | 6 | int main() 7 | { 8 | vector scores = { "F", "D", "C", "B", "A", "A++" }; 9 | 10 | int grade = 0; 11 | while (cin >> grade) 12 | { 13 | string lettergrade = grade < 60 ? scores[0] : scores[(grade - 50) / 10]; 14 | lettergrade += (grade == 100 || grade < 60) ? "" : (grade % 10 > 7) ? "+" : (grade % 10 < 3) ? "-" : ""; 15 | cout << lettergrade << endl; 16 | } 17 | 18 | 19 | return 0; 20 | } -------------------------------------------------------------------------------- /ch05/exercise5_9.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::cout; using std::endl; using std::cin; 4 | 5 | int main() 6 | { 7 | unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0; 8 | char ch; 9 | while (cin >> ch) 10 | { 11 | if (ch == 'a') ++aCnt; 12 | else if (ch == 'e') ++eCnt; 13 | else if (ch == 'i') ++iCnt; 14 | else if (ch == 'o') ++oCnt; 15 | else if (ch == 'u') ++uCnt; 16 | } 17 | cout << "Number of vowel a: \t" << aCnt << '\n' 18 | << "Number of vowel e: \t" << eCnt << '\n' 19 | << "Number of vowel i: \t" << iCnt << '\n' 20 | << "Number of vowel o: \t" << oCnt << '\n' 21 | << "Number of vowel u: \t" << uCnt << endl; 22 | 23 | return 0; 24 | } -------------------------------------------------------------------------------- /ch06/Chapter6.h: -------------------------------------------------------------------------------- 1 | int fact(int val); 2 | int func(); 3 | 4 | template 5 | T abs(T i) 6 | { 7 | return i >= 0 ? i : -i; 8 | } -------------------------------------------------------------------------------- /ch06/exercise6_10.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void swap(int* lhs, int* rhs) 5 | { 6 | int tmp; 7 | tmp = *lhs; 8 | *lhs = *rhs; 9 | *rhs = tmp; 10 | } 11 | 12 | int main() 13 | { 14 | for (int lft, rht; std::cout << "Please Enter:\n", std::cin >> lft >> rht;) 15 | { 16 | swap(&lft, &rht); 17 | std::cout << lft << " " << rht << std::endl; 18 | } 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /ch06/exercise6_11.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void reset(int &i) 4 | { 5 | i = 0; 6 | } 7 | 8 | int main() 9 | { 10 | int i = 42; 11 | reset(i); 12 | std::cout << i << std::endl; 13 | return 0; 14 | } -------------------------------------------------------------------------------- /ch06/exercise6_12.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | void swap(int& lhs, int& rhs) 6 | { 7 | int temp = lhs; 8 | lhs = rhs; 9 | rhs = temp; 10 | } 11 | 12 | int main() 13 | { 14 | for (int left, right; std::cout << "Please Enter:\n", std::cin >> left >> right;) 15 | { 16 | swap(left, right); 17 | std::cout << left << " " << right << std::endl; 18 | } 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /ch06/exercise6_17.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::cout; using std::endl; using std::string; 6 | 7 | bool any_capital(string const& str) 8 | { 9 | for (auto ch : str) 10 | if (isupper(ch)) return true; 11 | return false; 12 | } 13 | 14 | void to_lowercase(string& str) 15 | { 16 | for (auto& ch : str) ch = tolower(ch); 17 | } 18 | 19 | int main() 20 | { 21 | string hello("Hello World!"); 22 | cout << any_capital(hello) << endl; 23 | 24 | to_lowercase(hello); 25 | cout << hello << endl; 26 | 27 | return 0; 28 | } -------------------------------------------------------------------------------- /ch06/exercise6_21.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::cout; 3 | 4 | int larger_one(int i, const int *p) 5 | { 6 | return (i > *p) ? i : *p; 7 | } 8 | 9 | int main() 10 | { 11 | int i = 6; 12 | cout << larger_one(7, &i); 13 | 14 | return 0; 15 | } -------------------------------------------------------------------------------- /ch06/exercise6_22.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void swap(int*& lft, int*& rht) 5 | { 6 | auto tmp = lft; 7 | lft = rht; 8 | rht = tmp; 9 | } 10 | 11 | int main() 12 | { 13 | int i = 42, j = 99; 14 | auto lft = &i; 15 | auto rht = &j; 16 | swap(lft, rht); 17 | std::cout << *lft << " " << *rht << std::endl; 18 | 19 | return 0; 20 | } -------------------------------------------------------------------------------- /ch06/exercise6_23.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::cout; using std::endl; using std::begin; using std::end; 3 | 4 | void print(int i) 5 | { 6 | cout << i << endl; 7 | } 8 | 9 | void print(const int *beg, const int *end) 10 | { 11 | while (beg != end) 12 | cout << *beg++ << endl; 13 | } 14 | 15 | void print(const int ia[], size_t size) 16 | { 17 | for (size_t i = 0; i != size; ++i) 18 | { 19 | cout << ia[i] << endl; 20 | } 21 | } 22 | 23 | void print(int (&arr)[2]) 24 | { 25 | for (auto i : arr) 26 | cout << i << endl; 27 | } 28 | 29 | int main() 30 | { 31 | int i = 0, j[2] = { 0, 1 }; 32 | 33 | print(i); 34 | print(begin(j), end(j)); 35 | print(j, end(j) - begin(j)); 36 | print(j); 37 | 38 | return 0; 39 | } -------------------------------------------------------------------------------- /ch06/exercise6_25.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) 5 | { 6 | std::string str; 7 | for (int i = 1; i != argc; ++i) 8 | str += std::string(argv[i]) + " "; 9 | 10 | std::cout << str << std::endl; 11 | return 0; 12 | } -------------------------------------------------------------------------------- /ch06/exercise6_27.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int sum(std::initializer_list const& il) 5 | { 6 | int sum = 0; 7 | for (auto i : il) 8 | sum += i; 9 | return sum; 10 | } 11 | 12 | int main(void) 13 | { 14 | auto il = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 15 | std::cout << sum(il) << std::endl; 16 | 17 | return 0; 18 | } -------------------------------------------------------------------------------- /ch06/exercise6_3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int fact(int i) 4 | { 5 | return i > 1 ? i * fact(i - 1) : 1; 6 | } 7 | 8 | int main() 9 | { 10 | std::cout << fact(5) << std::endl; 11 | return 0; 12 | } -------------------------------------------------------------------------------- /ch06/exercise6_30.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | bool str_subrange(const string& str1, const string& str2) 7 | { 8 | if (str1.size() == str2.size()) 9 | return str1 == str2; 10 | auto size = (str1.size() < str2.size()) ? str1.size() : str2.size(); 11 | 12 | for (decltype(size) i = 0; i != size; ++i) 13 | { 14 | if (str1[i] != str2[i]) 15 | return; 16 | } 17 | } 18 | 19 | int main(void) 20 | { 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /ch06/exercise6_33.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | using Iter = vector::const_iterator; 7 | 8 | void print(Iter first, Iter last) 9 | { 10 | if (first == last) 11 | { 12 | cout << "over!" << endl; 13 | return; 14 | } 15 | cout << *first << " "; 16 | print(++first, last); 17 | 18 | } 19 | 20 | int main() 21 | { 22 | vector vec{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 23 | print(vec.cbegin(), vec.cend()); 24 | 25 | return 0; 26 | } -------------------------------------------------------------------------------- /ch06/exercise6_4.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int fact(int i) 5 | { 6 | return i > 1 ? i * fact(i - 1) : 1; 7 | } 8 | 9 | void interactive_fact() 10 | { 11 | std::string const prompt = "Enter a number within [1, 13) :\n"; 12 | std::string const out_of_range = "Out of range, please try again.\n"; 13 | for (int i; std::cout << prompt, std::cin >> i;) 14 | { 15 | if (i < 1 || i > 12) 16 | { 17 | std::cout << out_of_range; 18 | continue; 19 | } 20 | std::cout << fact(i) << std::endl; 21 | } 22 | } 23 | 24 | int main() 25 | { 26 | interactive_fact(); 27 | return 0; 28 | } -------------------------------------------------------------------------------- /ch06/exercise6_42.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::string; 5 | using std::cout; 6 | using std::endl; 7 | 8 | string make_plural(size_t ctr, const string& word, const string& ending = "s") 9 | { 10 | return (ctr > 1) ? word + ending : word; 11 | } 12 | 13 | int main() 14 | { 15 | cout << "singual: " << make_plural(1, "success", "es") << " " 16 | << make_plural(1, "failure") << endl; 17 | cout << "plural : " << make_plural(2, "success", "es") << " " 18 | << make_plural(2, "failure") << endl; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /ch06/exercise6_47.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | using Iter = vector::const_iterator; 7 | 8 | #define NDEBUG 9 | 10 | void print(Iter first, Iter last) 11 | { 12 | #ifndef NDEBUG 13 | cout << "vector size: " << last - first << endl; 14 | #endif 15 | if (first == last) 16 | { 17 | cout << "over!" << endl; 18 | return; 19 | } 20 | cout << *first << " "; 21 | print(++first, last); 22 | 23 | } 24 | 25 | int main() 26 | { 27 | vector vec{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 28 | print(vec.cbegin(), vec.cend()); 29 | 30 | return 0; 31 | } -------------------------------------------------------------------------------- /ch06/exercise6_51.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangmingchuan/Cpp_Primer_Answers/925506ca53f7b2e8501bc8eaaee3dba8c03d9ec2/ch06/exercise6_51.cpp -------------------------------------------------------------------------------- /ch06/exercise6_55.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int add(int a, int b) { return a + b; } 7 | int subtract(int a, int b) { return a - b; } 8 | int multiply(int a, int b) { return a * b; } 9 | int divide(int a, int b) { return b != 0 ? a / b : 0; } 10 | 11 | int main() 12 | { 13 | int func(int, int); 14 | vector v; 15 | v.push_back(add); 16 | v.push_back(subtract); 17 | v.push_back(multiply); 18 | v.push_back(divide); 19 | 20 | for (auto i : v) 21 | { 22 | cout << i(6, 2) << ", "; // 8, 4, 12, 3 23 | } 24 | cout << endl; 25 | return 0; 26 | } -------------------------------------------------------------------------------- /ch06/fact.cpp: -------------------------------------------------------------------------------- 1 | #include "Chapter6.h" 2 | #include 3 | 4 | int fact(int val) 5 | { 6 | if (val == 0 || val == 1) return 1; 7 | else return val * fact(val - 1); 8 | } 9 | 10 | int func() 11 | { 12 | int n, ret = 1; 13 | std::cout << "input a number: "; 14 | std::cin >> n; 15 | while (n > 1) ret *= n--; 16 | return ret; 17 | } -------------------------------------------------------------------------------- /ch06/factMain.cpp: -------------------------------------------------------------------------------- 1 | #include "Chapter6.h" 2 | #include 3 | 4 | int main() 5 | { 6 | std::cout << "5! is " << fact(5) << std::endl; 7 | std::cout << func() << std::endl; 8 | std::cout << abs(-9.78) << std::endl; 9 | } -------------------------------------------------------------------------------- /ch07/exercise7_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::cin; using std::cout; using std::endl; using std::string; 4 | 5 | struct Sales_data 6 | { 7 | string bookNo; 8 | unsigned units_sold = 0; 9 | double revenue = 0.0; 10 | }; 11 | 12 | int main() 13 | { 14 | Sales_data total; 15 | if (cin >> total.bookNo >> total.units_sold >> total.revenue) 16 | { 17 | Sales_data trans; 18 | while (cin >> trans.bookNo >> trans.units_sold >> trans.revenue) 19 | { 20 | if (total.bookNo == trans.bookNo) 21 | { 22 | total.units_sold += trans.units_sold; 23 | total.revenue += trans.revenue; 24 | } 25 | else 26 | { 27 | cout << total.bookNo << " " << total.units_sold << " " << total.revenue << endl; 28 | total = trans; 29 | } 30 | } 31 | cout << total.bookNo << " " << total.units_sold << " " << total.revenue << endl; 32 | } 33 | else 34 | { 35 | std::cerr << "No data?!" << std::endl; 36 | return -1; 37 | } 38 | return 0; 39 | } -------------------------------------------------------------------------------- /ch07/exercise7_11.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise7_11.h" 2 | 3 | int main() 4 | { 5 | Sales_data item1; 6 | print(std::cout, item1) << std::endl; 7 | 8 | Sales_data item2("0-201-78345-X"); 9 | print(std::cout, item2) << std::endl; 10 | 11 | Sales_data item3("0-201-78345-X", 3, 20.00); 12 | print(std::cout, item3) << std::endl; 13 | 14 | Sales_data item4(std::cin); 15 | print(std::cout, item4) << std::endl; 16 | 17 | return 0; 18 | } -------------------------------------------------------------------------------- /ch07/exercise7_11.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_11_h 2 | #define CP5_ex7_11_h 3 | 4 | #include 5 | #include 6 | 7 | struct Sales_data 8 | { 9 | Sales_data() = default; 10 | Sales_data(const std::string &s) :bookNo(s) {} 11 | Sales_data(const std::string &s, unsigned n, double p) :bookNo(s), units_sold(n), revenue(n*p) {} 12 | Sales_data(std::istream &is); 13 | 14 | std::string isbn() const { return bookNo; }; 15 | Sales_data& combine(const Sales_data&); 16 | 17 | std::string bookNo; 18 | unsigned units_sold = 0; 19 | double revenue = 0.0; 20 | }; 21 | 22 | std::istream &read(std::istream &is, Sales_data &item) 23 | { 24 | double price = 0; 25 | is >> item.bookNo >> item.units_sold >> price; 26 | item.revenue = price * item.units_sold; 27 | return is; 28 | } 29 | 30 | std::ostream &print(std::ostream &os, const Sales_data &item) 31 | { 32 | os << item.isbn() << " " << item.units_sold << " " << item.revenue; 33 | return os; 34 | } 35 | 36 | Sales_data add(const Sales_data &lhs, const Sales_data &rhs) 37 | { 38 | Sales_data sum = lhs; 39 | sum.combine(rhs); 40 | return sum; 41 | } 42 | 43 | Sales_data::Sales_data(std::istream &is) 44 | { 45 | read(is, *this); 46 | } 47 | 48 | Sales_data& Sales_data::combine(const Sales_data& rhs) 49 | { 50 | units_sold += rhs.units_sold; 51 | revenue += rhs.revenue; 52 | return *this; 53 | } 54 | 55 | #endif -------------------------------------------------------------------------------- /ch07/exercise7_12.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_12_h 2 | #define CP5_ex7_12_h 3 | 4 | #include 5 | #include 6 | 7 | struct Sales_data; 8 | std::istream &read(std::istream&, Sales_data&); 9 | 10 | struct Sales_data 11 | { 12 | Sales_data() = default; 13 | Sales_data(const std::string &s) :bookNo(s) {} 14 | Sales_data(const std::string &s, unsigned n, double p) :bookNo(s), units_sold(n), revenue(n*p) {} 15 | Sales_data(std::istream &is) { read(is, *this); } 16 | 17 | std::string isbn() const { return bookNo; }; 18 | Sales_data& combine(const Sales_data&); 19 | 20 | std::string bookNo; 21 | unsigned units_sold = 0; 22 | double revenue = 0.0; 23 | }; 24 | 25 | Sales_data& Sales_data::combine(const Sales_data& rhs) 26 | { 27 | units_sold += rhs.units_sold; 28 | revenue += rhs.revenue; 29 | return *this; 30 | } 31 | 32 | std::istream &read(std::istream &is, Sales_data &item) 33 | { 34 | double price = 0; 35 | is >> item.bookNo >> item.units_sold >> price; 36 | item.revenue = price * item.units_sold; 37 | return is; 38 | } 39 | 40 | std::ostream &print(std::ostream &os, const Sales_data &item) 41 | { 42 | os << item.isbn() << " " << item.units_sold << " " << item.revenue; 43 | return os; 44 | } 45 | 46 | Sales_data add(const Sales_data &lhs, const Sales_data &rhs) 47 | { 48 | Sales_data sum = lhs; 49 | sum.combine(rhs); 50 | return sum; 51 | } 52 | 53 | #endif -------------------------------------------------------------------------------- /ch07/exercise7_13.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise7_12.h" 2 | 3 | int main() 4 | { 5 | Sales_data total(std::cin); 6 | if (!total.isbn().empty()) 7 | { 8 | std::istream &is = std::cin; 9 | while (is) 10 | { 11 | Sales_data trans(is); 12 | if (total.isbn() == trans.isbn()) 13 | total.combine(trans); 14 | else 15 | { 16 | print(std::cout, total) << std::endl; 17 | total = trans; 18 | } 19 | } 20 | print(std::cout, total) << std::endl; 21 | } 22 | else 23 | { 24 | std::cerr << "No data?!" << std::endl; 25 | return -1; 26 | } 27 | 28 | return 0; 29 | } -------------------------------------------------------------------------------- /ch07/exercise7_15.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_15_h 2 | #define CP5_ex7_15_h 3 | 4 | #include 5 | #include 6 | 7 | struct Person; 8 | std::istream &read(std::istream&, Person&); 9 | 10 | struct Person 11 | { 12 | Person() = default; 13 | Person(const std::string& sname, const std::string& saddr) :name(sname), address(saddr) {} 14 | Person(std::istream &is) { read(is, *this); } 15 | 16 | std::string getName() const { return name; } 17 | std::string getAddress() const { return address; } 18 | 19 | std::string name; 20 | std::string address; 21 | }; 22 | 23 | std::istream &read(std::istream &is, Person &person) 24 | { 25 | is >> person.name >> person.address; 26 | return is; 27 | } 28 | 29 | std::ostream &print(std::ostream &os, const Person &person) 30 | { 31 | os << person.name << " " << person.address; 32 | return os; 33 | } 34 | 35 | #endif -------------------------------------------------------------------------------- /ch07/exercise7_2.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_02_h 2 | #define CP5_ex7_02_h 3 | 4 | #include 5 | 6 | struct Sales_data 7 | { 8 | std::string isbn() const { return bookNo; }; 9 | Sales_data& combine(const Sales_data&); 10 | 11 | std::string bookNo; 12 | unsigned units_sold = 0; 13 | double revenue = 0.0; 14 | }; 15 | 16 | Sales_data& Sales_data::combine(const Sales_data& rhs) 17 | { 18 | units_sold += rhs.units_sold; 19 | revenue += rhs.revenue; 20 | return *this; 21 | } 22 | 23 | #endif -------------------------------------------------------------------------------- /ch07/exercise7_21.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_21_h 2 | #define CP5_ex7_21_h 3 | 4 | #include 5 | #include 6 | 7 | class Sales_data 8 | { 9 | friend std::istream &read(std::istream &is, Sales_data &item); 10 | friend std::ostream &print(std::ostream &os, const Sales_data &item); 11 | friend Sales_data add(const Sales_data &lhs, const Sales_data &rhs); 12 | 13 | public: 14 | Sales_data() = default; 15 | Sales_data(const std::string &s) :bookNo(s) {} 16 | Sales_data(const std::string &s, unsigned n, double p) :bookNo(s), units_sold(n), revenue(n*p) {} 17 | Sales_data(std::istream &is) { read(is, *this); } 18 | 19 | std::string isbn() const { return bookNo; }; 20 | Sales_data& combine(const Sales_data&); 21 | 22 | private: 23 | std::string bookNo; 24 | unsigned units_sold = 0; 25 | double revenue = 0.0; 26 | }; 27 | 28 | Sales_data& Sales_data::combine(const Sales_data& rhs) 29 | { 30 | units_sold += rhs.units_sold; 31 | revenue += rhs.revenue; 32 | return *this; 33 | } 34 | 35 | std::istream &read(std::istream &is, Sales_data &item) 36 | { 37 | double price = 0; 38 | is >> item.bookNo >> item.units_sold >> price; 39 | item.revenue = price * item.units_sold; 40 | return is; 41 | } 42 | 43 | std::ostream &print(std::ostream &os, const Sales_data &item) 44 | { 45 | os << item.isbn() << " " << item.units_sold << " " << item.revenue; 46 | return os; 47 | } 48 | 49 | Sales_data add(const Sales_data &lhs, const Sales_data &rhs) 50 | { 51 | Sales_data sum = lhs; 52 | sum.combine(rhs); 53 | return sum; 54 | } 55 | 56 | #endif -------------------------------------------------------------------------------- /ch07/exercise7_22.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_22_h 2 | #define CP5_ex7_22_h 3 | 4 | #include 5 | #include 6 | 7 | struct Person 8 | { 9 | friend std::istream &read(std::istream &is, Person &person); 10 | friend std::ostream &print(std::ostream &os, const Person &person); 11 | 12 | public: 13 | Person() = default; 14 | Person(const std::string sname, const std::string saddr) :name(sname), address(saddr) {} 15 | Person(std::istream &is) { read(is, *this); } 16 | 17 | std::string getName() const { return name; } 18 | std::string getAddress() const { return address; } 19 | private: 20 | std::string name; 21 | std::string address; 22 | }; 23 | 24 | std::istream &read(std::istream &is, Person &person) 25 | { 26 | is >> person.name >> person.address; 27 | return is; 28 | } 29 | 30 | std::ostream &print(std::ostream &os, const Person &person) 31 | { 32 | os << person.name << " " << person.address; 33 | return os; 34 | } 35 | 36 | #endif -------------------------------------------------------------------------------- /ch07/exercise7_23.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_23_h 2 | #define CP5_ex7_23_h 3 | #include 4 | 5 | class Screen 6 | { 7 | public: 8 | using pos = std::string::size_type; 9 | 10 | Screen() = default; 11 | Screen(pos ht, pos wd, char c) :height(ht), width(wd), contents(ht*wd, c) 12 | {} 13 | 14 | char get() const { return contents[cursor]; } 15 | char get(pos r, pos c) const { return contents[r*width + c]; } 16 | 17 | private: 18 | pos cursor = 0; 19 | pos height = 0; 20 | pos width = 0; 21 | std::string contents; 22 | }; 23 | 24 | #endif -------------------------------------------------------------------------------- /ch07/exercise7_24.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_24_h 2 | #define CP5_ex7_24_h 3 | #include 4 | 5 | class Screen 6 | { 7 | public: 8 | using pos = std::string::size_type; 9 | 10 | Screen() = default; 11 | Screen(pos ht, pos wd) :height(ht), width(wd), contents(ht*wd, ' ') {} 12 | Screen(pos ht, pos wd, char c) :height(ht), width(wd), contents(ht*wd, c) {} 13 | 14 | char get() const { return contents[cursor]; } 15 | char get(pos r, pos c) const { return contents[r*width + c]; } 16 | 17 | private: 18 | pos cursor = 0; 19 | pos height = 0; 20 | pos width = 0; 21 | std::string contents; 22 | }; 23 | 24 | #endif -------------------------------------------------------------------------------- /ch07/exercise7_26.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_26_h 2 | #define CP5_ex7_26_h 3 | 4 | #include 5 | #include 6 | 7 | class Sales_data 8 | { 9 | friend std::istream &read(std::istream &is, Sales_data &item); 10 | friend std::ostream &print(std::ostream &os, const Sales_data &item); 11 | friend Sales_data add(const Sales_data &lhs, const Sales_data &rhs); 12 | 13 | public: 14 | Sales_data() = default; 15 | Sales_data(const std::string &s) :bookNo(s) {} 16 | Sales_data(const std::string &s, unsigned n, double p) :bookNo(s), units_sold(n), revenue(n*p) {} 17 | Sales_data(std::istream &is) { read(is, *this); } 18 | 19 | std::string isbn() const { return bookNo; }; 20 | Sales_data& combine(const Sales_data&); 21 | 22 | private: 23 | inline double avg_price() const; 24 | 25 | private: 26 | std::string bookNo; 27 | unsigned units_sold = 0; 28 | double revenue = 0.0; 29 | }; 30 | 31 | inline 32 | double Sales_data::avg_price() const 33 | { 34 | return units_sold ? revenue / units_sold : 0; 35 | } 36 | 37 | std::istream &read(std::istream &is, Sales_data &item); 38 | std::ostream &print(std::ostream &os, const Sales_data &item); 39 | Sales_data add(const Sales_data &lhs, const Sales_data &rhs); 40 | 41 | #endif -------------------------------------------------------------------------------- /ch07/exercise7_27.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise7_27.h" 2 | 3 | int main() 4 | { 5 | Screen myScreen(5, 5, 'X'); 6 | myScreen.move(4, 0).set('#').display(std::cout); 7 | std::cout << "\n"; 8 | myScreen.display(std::cout); 9 | std::cout << "\n"; 10 | 11 | return 0; 12 | } -------------------------------------------------------------------------------- /ch07/exercise7_27.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_27_h 2 | #define CP5_ex7_27_h 3 | 4 | #include 5 | #include 6 | 7 | class Screen 8 | { 9 | public: 10 | using pos = std::string::size_type; 11 | 12 | Screen() = default; // 1 13 | Screen(pos ht, pos wd) :height(ht), width(wd), contents(ht*wd, ' ') {} // 2 14 | Screen(pos ht, pos wd, char c) :height(ht), width(wd), contents(ht*wd, c) {} // 3 15 | 16 | char get() const { return contents[cursor]; } 17 | char get(pos r, pos c) const { return contents[r*width + c]; } 18 | inline Screen& move(pos r, pos c); 19 | inline Screen& set(char c); 20 | inline Screen& set(pos r, pos c, char ch); 21 | 22 | const Screen& display(std::ostream &os) const { do_display(os); return *this; } 23 | Screen& display(std::ostream &os) { do_display(os); return *this; } 24 | 25 | private: 26 | void do_display(std::ostream &os) const { os << contents; } 27 | 28 | private: 29 | pos cursor = 0; 30 | pos height = 0, width = 0; 31 | std::string contents; 32 | }; 33 | 34 | inline Screen& Screen::move(pos r, pos c) 35 | { 36 | cursor = r*width + c; 37 | return *this; 38 | } 39 | 40 | inline Screen& Screen::set(char c) 41 | { 42 | contents[cursor] = c; 43 | return *this; 44 | } 45 | 46 | inline Screen& Screen::set(pos r, pos c, char ch) 47 | { 48 | contents[r*width + c] = ch; 49 | return *this; 50 | } 51 | 52 | #endif -------------------------------------------------------------------------------- /ch07/exercise7_3.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise7_2.h" 2 | #include 3 | using std::cin; using std::cout; using std::endl; 4 | 5 | int main() 6 | { 7 | Sales_data total; 8 | if (cin >> total.bookNo >> total.units_sold >> total.revenue) 9 | { 10 | Sales_data trans; 11 | while (cin >> trans.bookNo >> trans.units_sold >> trans.revenue) 12 | { 13 | if (total.isbn() == trans.isbn()) 14 | total.combine(trans); 15 | else 16 | { 17 | cout << total.bookNo << " " << total.units_sold << " " << total.revenue << endl; 18 | total = trans; 19 | } 20 | } 21 | cout << total.bookNo << " " << total.units_sold << " " << total.revenue << endl; 22 | } 23 | else 24 | { 25 | std::cerr << "No data?!" << std::endl; 26 | return -1; 27 | } 28 | 29 | return 0; 30 | } -------------------------------------------------------------------------------- /ch07/exercise7_32.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_32_h 2 | #define CP5_ex7_32_h 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class Screen; 9 | 10 | class Window_mgr 11 | { 12 | public: 13 | using ScreenIndex = std::vector::size_type; 14 | inline void clear(ScreenIndex); 15 | 16 | private: 17 | std::vector screens; 18 | }; 19 | 20 | class Screen 21 | { 22 | friend void Window_mgr::clear(ScreenIndex); 23 | 24 | public: 25 | using pos = std::string::size_type; 26 | 27 | Screen() = default; 28 | Screen(pos ht, pos wd) :height(ht), width(wd), contents(ht*wd,' ') {} 29 | Screen(pos ht, pos wd, char c) :height(ht), width(wd), contents(ht*wd, c) {} 30 | 31 | char get() const { return contents[cursor]; } 32 | char get(pos r, pos c) const { return contents[r*width + c]; } 33 | inline Screen& move(pos r, pos c); 34 | inline Screen& set(char c); 35 | inline Screen& set(pos r, pos c, char ch); 36 | 37 | const Screen& display(std::ostream& os) const { do_display(os); return *this; } 38 | Screen& display(std::ostream& os) { do_display(os); return *this; } 39 | 40 | private: 41 | void do_display(std::ostream &os) const { os << contents; } 42 | 43 | private: 44 | pos cursor = 0; 45 | pos width = 0, height = 0; 46 | std::string contents; 47 | }; 48 | 49 | 50 | inline void Window_mgr::clear(ScreenIndex i) 51 | { 52 | Screen& s = screens[i]; 53 | s.contents = std::string(s.height*s.width,' '); 54 | } 55 | 56 | inline Screen& Screen::move(pos r, pos c) 57 | { 58 | cursor = r*width + c; 59 | return *this; 60 | } 61 | 62 | inline Screen& Screen::set(char c) 63 | { 64 | contents[cursor] = c; 65 | return *this; 66 | } 67 | 68 | inline Screen& Screen::set(pos r, pos c, char ch) 69 | { 70 | contents[r*width + c] = ch; 71 | return *this; 72 | } 73 | 74 | 75 | #endif -------------------------------------------------------------------------------- /ch07/exercise7_4.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_04_h 2 | #define CP5_ex7_04_h 3 | 4 | #include 5 | 6 | class Person 7 | { 8 | std::string name; 9 | std::string address; 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /ch07/exercise7_41.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise7_41.h" 2 | 3 | Sales_data::Sales_data(std::istream &is) : Sales_data() 4 | { 5 | std::cout << "Sales_data(istream &is)" << std::endl; 6 | read(is, *this); 7 | } 8 | 9 | Sales_data& Sales_data::combine(const Sales_data& rhs) 10 | { 11 | units_sold += rhs.units_sold; 12 | revenue += rhs.revenue; 13 | return *this; 14 | } 15 | 16 | std::istream &read(std::istream &is, Sales_data &item) 17 | { 18 | double price = 0; 19 | is >> item.bookNo >> item.units_sold >> price; 20 | item.revenue = price * item.units_sold; 21 | return is; 22 | } 23 | 24 | std::ostream &print(std::ostream &os, const Sales_data &item) 25 | { 26 | os << item.isbn() << " " << item.units_sold << " " << item.revenue; 27 | return os; 28 | } 29 | 30 | Sales_data add(const Sales_data &lhs, const Sales_data &rhs) 31 | { 32 | Sales_data sum = lhs; 33 | sum.combine(rhs); 34 | return sum; 35 | } -------------------------------------------------------------------------------- /ch07/exercise7_41.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_41_h 2 | #define CP5_ex7_41_h 3 | 4 | #include 5 | #include 6 | 7 | class Sales_data 8 | { 9 | friend std::istream &read(std::istream &is, Sales_data &item); 10 | friend std::ostream &print(std::ostream &os, const Sales_data &item); 11 | friend Sales_data add(const Sales_data &lhs, const Sales_data &rhs); 12 | 13 | public: 14 | Sales_data(const std::string &s, unsigned n, double p) :bookNo(s), units_sold(n), revenue(n*p) 15 | { 16 | std::cout << "Sales_data(const std::string&, unsigned, double)" << std::endl; 17 | } 18 | 19 | Sales_data() : Sales_data("", 0, 0.0f) 20 | { 21 | std::cout << "Sales_data()" << std::endl; 22 | } 23 | 24 | Sales_data(const std::string &s) : Sales_data(s, 0, 0.0f) 25 | { 26 | std::cout << "Sales_data(const std::string&)" << std::endl; 27 | } 28 | 29 | Sales_data(std::istream &is); 30 | 31 | std::string isbn() const { return bookNo; } 32 | Sales_data& combine(const Sales_data&); 33 | 34 | private: 35 | inline double avg_price() const; 36 | 37 | private: 38 | std::string bookNo; 39 | unsigned units_sold = 0; 40 | double revenue = 0.0; 41 | }; 42 | 43 | inline 44 | double Sales_data::avg_price() const 45 | { 46 | return units_sold ? revenue / units_sold : 0; 47 | } 48 | 49 | std::istream &read(std::istream &is, Sales_data &item); 50 | std::ostream &print(std::ostream &os, const Sales_data &item); 51 | Sales_data add(const Sales_data &lhs, const Sales_data &rhs); 52 | 53 | #endif -------------------------------------------------------------------------------- /ch07/exercise7_41_main.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise7_41.h" 2 | 3 | using std::cout; using std::endl; 4 | 5 | int main() 6 | { 7 | cout << "1. default way: " << endl; 8 | cout << "----------------" << endl; 9 | Sales_data s1; 10 | 11 | cout << "\n2. use std::string as parameter: " << endl; 12 | cout << "----------------" << endl; 13 | Sales_data s2("CPP-Primer-5th"); 14 | 15 | cout << "\n3. complete parameters: " << endl; 16 | cout << "----------------" << endl; 17 | Sales_data s3("CPP-Primer-5th", 3, 25.8); 18 | 19 | cout << "\n4. use istream as parameter: " << endl; 20 | cout << "----------------" << endl; 21 | Sales_data s4(std::cin); 22 | 23 | return 0; 24 | } -------------------------------------------------------------------------------- /ch07/exercise7_5.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_05_h 2 | #define CP5_ex7_05_h 3 | 4 | #include 5 | 6 | class Person 7 | { 8 | std::string name; 9 | std::string address; 10 | public: 11 | auto get_name() const -> std::string const& { return name; } 12 | auto get_addr() const -> std::string const& { return address; } 13 | }; 14 | 15 | #endif -------------------------------------------------------------------------------- /ch07/exercise7_6.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_06_h 2 | #define CP5_ex7_06_h 3 | 4 | #include 5 | #include 6 | 7 | struct Sales_data 8 | { 9 | std::string const& isbn() const { return bookNo; }; 10 | Sales_data& combine(const Sales_data&); 11 | 12 | std::string bookNo; 13 | unsigned units_sold = 0; 14 | double revenue = 0.0; 15 | }; 16 | 17 | Sales_data& Sales_data::combine(const Sales_data& rhs) 18 | { 19 | units_sold += rhs.units_sold; 20 | revenue += rhs.revenue; 21 | return *this; 22 | } 23 | 24 | std::istream &read(std::istream &is, Sales_data &item) 25 | { 26 | double price = 0; 27 | is >> item.bookNo >> item.units_sold >> price; 28 | item.revenue = price * item.units_sold; 29 | return is; 30 | } 31 | 32 | std::ostream &print(std::ostream &os, const Sales_data &item) 33 | { 34 | os << item.isbn() << " " << item.units_sold << " " << item.revenue; 35 | return os; 36 | } 37 | 38 | Sales_data add(const Sales_data &lhs, const Sales_data &rhs) 39 | { 40 | Sales_data sum = lhs; 41 | sum.combine(rhs); 42 | return sum; 43 | } 44 | 45 | #endif -------------------------------------------------------------------------------- /ch07/exercise7_7.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise7_6.h" 2 | 3 | int main() 4 | { 5 | Sales_data total; 6 | if (read(std::cin, total)) 7 | { 8 | Sales_data trans; 9 | while (read(std::cin, trans)) 10 | { 11 | if (total.isbn() == trans.isbn()) 12 | total.combine(trans); 13 | else 14 | { 15 | print(std::cout, total) << std::endl; 16 | total = trans; 17 | } 18 | } 19 | print(std::cout, total) << std::endl; 20 | } 21 | else 22 | { 23 | std::cerr << "No data?!" << std::endl; 24 | return -1; 25 | } 26 | 27 | return 0; 28 | } -------------------------------------------------------------------------------- /ch07/exercise7_9.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_09_h 2 | #define CP5_ex7_09_h 3 | 4 | #include 5 | #include 6 | 7 | struct Person 8 | { 9 | std::string const& getName() const { return name; } 10 | std::string const& getAddress() const { return address; } 11 | 12 | std::string name; 13 | std::string address; 14 | }; 15 | 16 | std::istream &read(std::istream &is, Person &person) 17 | { 18 | return is >> person.name >> person.address; 19 | } 20 | 21 | std::ostream &print(std::ostream &os, const Person &person) 22 | { 23 | return os << person.name << " " << person.address; 24 | } 25 | 26 | #endif -------------------------------------------------------------------------------- /ch08/README.md: -------------------------------------------------------------------------------- 1 | ## 练习8.1 2 | 3 | > 编写函数,接受一个istream&参数,返回值类型也是istream&。此函数须从给定流中读取数据,直至遇到文件结束标识时停止。它将读取的数据打印在标准输出上。完成这些操作后,在返回流之前,对流进行复位,使其处于有效状态。 4 | 5 | ```cpp 6 | std::istream& func(std::istream &is) 7 | { 8 | std::string buf; 9 | while (is >> buf) 10 | std::cout << buf << std::endl; 11 | is.clear(); 12 | return is; 13 | } 14 | ``` 15 | 16 | ## [练习8.2](exercise8_2.cpp) 17 | 18 | > 测试函数,调用参数为cin。 19 | 20 | ## 练习8.3 21 | 22 | > 什么情况下,下面的while循环会终止? 23 | ```cpp 24 | while (cin >> i) /* ... */ 25 | ``` 26 | 27 | 如果 `badbit`、`failbit`、`eofbit` 的任一个被置位,那么检测流状态的条件会失败。 28 | 29 | ## 练习8.4 30 | 31 | > 编写函数,以读模式打开一个文件,将其内容读入到一个string的vector中,将每一行作为一个独立的元素存于vector中。 32 | 33 | ```cpp 34 | void ReadFileToVec(const string& fileName, vector& vec) 35 | { 36 | ifstream ifs(fileName); 37 | if (ifs) 38 | { 39 | string buf; 40 | while (getline(ifs, buf)) 41 | vec.push_back(buf); 42 | } 43 | } 44 | ``` 45 | 46 | ## 练习8.5 47 | 48 | > 重写上面的程序,将每个单词作为一个独立的元素进行存储。 49 | 50 | ```cpp 51 | void ReadFileToVec(const string& fileName, vector& vec) 52 | { 53 | ifstream ifs(fileName); 54 | if (ifs) 55 | { 56 | string buf; 57 | while (ifs >> buf) 58 | vec.push_back(buf); 59 | } 60 | } 61 | ``` 62 | 63 | ## [练习8.6](exercise8_6.cpp) 64 | 65 | > 重写7.1.1节的书店程序,从一个文件中读取交易记录。将文件名作为一个参数传递给main。 66 | 67 | ## [练习8.7](exercise8_7.cpp) 68 | 69 | > 修改上一节的书店程序,将结果保存到一个文件中。将输出文件名作为第二个参数传递给main函数。 70 | 71 | ## [练习8.8](exercise8_8.cpp) 72 | 73 | > 修改上一题的程序,将结果追加到给定的文件末尾。对同一个输出文件,运行程序至少两次,检验数据是否得以保留。 74 | 75 | ## [练习8.9](exercise8_9.cpp) 76 | 77 | > 使用你为8.1.2节第一个练习所编写的函数打印一个istringstream对象的内容。 78 | 79 | ## [练习8.10](exercise8_10.cpp) 80 | 81 | > 编写程序,将来自一个文件中的行保存在一个vector中。然后使用一个istringstream从vector读取数据元素,每次读取一个单词。 82 | 83 | ## [练习8.11](exercise8_11.cpp) 84 | 85 | > 本节的程序在外层while循环中定义了istringstream 对象。如果record 对象定义在循环之外,你需要对程序进行怎样的修改?重写程序,将record的定义移到while 循环之外,验证你设想的修改方法是否正确。 86 | 87 | ## 练习8.12 88 | 89 | > 我们为什么没有在PersonInfo中使用类内初始化? 90 | 91 | 因为这里只需要聚合类就够了,所以没有必要在 PersionInfo 中使用类内初始化。 92 | 93 | ## [练习8.13](exercise8_13.cpp) 94 | 95 | > 重写本节的电话号码程序,从一个命名文件而非cin读取数据。 96 | 97 | ## 练习8.14 98 | 99 | > 我们为什么将entry和nums定义为 const auto& ? 100 | 101 | * 它们都是类类型,因此使用引用避免拷贝。 102 | * 在循环当中不会改变它们的值,因此用 const。 -------------------------------------------------------------------------------- /ch08/exercise8_10.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using std::vector; using std::string; using std::ifstream; using std::istringstream; using std::cout; using std::endl; using std::cerr; 8 | 9 | int main() 10 | { 11 | ifstream ifs("E:/code/cpp_primer_answer/Cpp_Primer_Answers/data/books.txt"); 12 | if (!ifs) 13 | { 14 | cerr << "No data?" << endl; 15 | return -1; 16 | } 17 | 18 | vector vecLine; 19 | string line; 20 | while (getline(ifs, line)) 21 | vecLine.push_back(line); 22 | 23 | for (auto &s : vecLine) 24 | { 25 | istringstream iss(s); 26 | string word; 27 | while (iss >> word) 28 | cout << word << ", "; 29 | cout << endl; 30 | } 31 | 32 | return 0; 33 | } -------------------------------------------------------------------------------- /ch08/exercise8_11.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using std::vector; using std::string; using std::cin; using std::istringstream; 6 | 7 | struct PersonInfo 8 | { 9 | string name; 10 | vector phones; 11 | }; 12 | 13 | int main() 14 | { 15 | string line, word; 16 | vector people; 17 | istringstream record; 18 | while (getline(cin, line)) 19 | { 20 | PersonInfo info; 21 | record.clear(); 22 | record.str(line); 23 | record >> info.name; 24 | while (record >> word) 25 | info.phones.push_back(word); 26 | people.push_back(info); 27 | } 28 | 29 | for (auto &p : people) 30 | { 31 | std::cout << p.name << " "; 32 | for (auto &s : p.phones) 33 | std::cout << s << " "; 34 | std::cout << std::endl; 35 | } 36 | 37 | return 0; 38 | } -------------------------------------------------------------------------------- /ch08/exercise8_13.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using std::vector; using std::string; using std::cin; using std::istringstream; 9 | using std::ostringstream; using std::ifstream; using std::cerr; using std::cout; using std::endl; 10 | 11 | struct PersonInfo 12 | { 13 | string name; 14 | vector phones; 15 | }; 16 | 17 | bool valid(const string& str) 18 | { 19 | return isdigit(str[0]); 20 | } 21 | 22 | string format(const string& str) 23 | { 24 | return str.substr(0, 3) + "-" + str.substr(3, 3) + "-" + str.substr(6); 25 | } 26 | 27 | int main() 28 | { 29 | ifstream ifs("E:/code/cpp_primer_answer/Cpp_Primer_Answers/data/phonenumbers.txt"); 30 | if (!ifs) 31 | { 32 | cerr << "no phone numbers?" << endl; 33 | return -1; 34 | } 35 | 36 | string line, word; 37 | vector people; 38 | istringstream record; 39 | while (getline(ifs, line)) 40 | { 41 | PersonInfo info; 42 | record.clear(); 43 | record.str(line); 44 | record >> info.name; 45 | while (record >> word) 46 | info.phones.push_back(word); 47 | people.push_back(info); 48 | } 49 | 50 | for (const auto &entry : people) 51 | { 52 | ostringstream formatted, badNums; 53 | for (const auto &nums : entry.phones) 54 | if (!valid(nums)) badNums << " " << nums; 55 | else formatted << " " << format(nums); 56 | if (badNums.str().empty()) 57 | cout << entry.name << " " << formatted.str() << endl; 58 | else 59 | cerr << "input error: " << entry.name 60 | << " invalid number(s) " << badNums.str() << endl; 61 | } 62 | 63 | return 0; 64 | } -------------------------------------------------------------------------------- /ch08/exercise8_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | istream& func(istream &is) 7 | { 8 | string buf; 9 | while (is >> buf) 10 | cout << buf << endl; 11 | is.clear(); 12 | return is; 13 | } 14 | 15 | int main() 16 | { 17 | istream& is = func(std::cin); 18 | cout << is.rdstate() << endl; 19 | return 0; 20 | } -------------------------------------------------------------------------------- /ch08/exercise8_6.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "exercise7_26.h" 5 | 6 | using namespace std; 7 | 8 | int main(int argc, char **argv) 9 | { 10 | ifstream input(argv[1]); 11 | 12 | Sales_data total; 13 | if (read(input, total)) 14 | { 15 | Sales_data trans; 16 | while (read(input, trans)) 17 | { 18 | if (total.isbn() == trans.isbn()) 19 | total.combine(trans); 20 | else 21 | { 22 | print(cout, total) << endl; 23 | total = trans; 24 | } 25 | } 26 | print(cout, total) << endl; 27 | } 28 | else 29 | { 30 | cerr << "No data?!" << endl; 31 | } 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /ch08/exercise8_7.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "exercise7_26.h" 5 | 6 | using std::ifstream; using std::ofstream; using std::endl; using std::cerr; 7 | 8 | int main(int argc, char **argv) 9 | { 10 | ifstream input(argv[1]); 11 | ofstream output(argv[2]); 12 | 13 | Sales_data total; 14 | if (read(input, total)) 15 | { 16 | Sales_data trans; 17 | while (read(input, trans)) 18 | { 19 | if (total.isbn() == trans.isbn()) 20 | total.combine(trans); 21 | else 22 | { 23 | print(output, total) << endl; 24 | total = trans; 25 | } 26 | } 27 | print(output, total) << endl; 28 | } 29 | else 30 | { 31 | cerr << "No data?!" << endl; 32 | } 33 | 34 | return 0; 35 | } -------------------------------------------------------------------------------- /ch08/exercise8_8.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "exercise7_26.h" 5 | 6 | using std::ifstream; using std::ofstream; using std::endl; using std::cerr; 7 | 8 | int main(int argc, char **argv) 9 | { 10 | ifstream input(argv[1]); 11 | ofstream output(argv[2], ofstream::app); 12 | 13 | Sales_data total; 14 | if (read(input, total)) 15 | { 16 | Sales_data trans; 17 | while (read(input, trans)) 18 | { 19 | if (total.isbn() == trans.isbn()) 20 | total.combine(trans); 21 | else 22 | { 23 | print(output, total) << endl; 24 | total = trans; 25 | } 26 | } 27 | print(output, total) << endl; 28 | } 29 | else 30 | { 31 | cerr << "No data?!" << endl; 32 | } 33 | 34 | return 0; 35 | } -------------------------------------------------------------------------------- /ch08/exercise8_9.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::istream; 5 | 6 | istream& func(istream &is) 7 | { 8 | std::string buf; 9 | while (is >> buf) 10 | std::cout << buf << std::endl; 11 | is.clear(); 12 | return is; 13 | } 14 | 15 | int main() 16 | { 17 | std::istringstream iss("hello"); 18 | func(iss); 19 | return 0; 20 | } -------------------------------------------------------------------------------- /ch09/exercise9_13.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using std::list; using std::vector; using std::cout; using std::endl; 7 | 8 | int main() 9 | { 10 | list ilst(5, 4); 11 | vector ivc(5, 5); 12 | 13 | // from list to vector 14 | vector dvc(ilst.begin(), ilst.end()); 15 | for (auto i : ilst) cout << i << " "; 16 | cout << endl; 17 | for (auto d : dvc) cout << d << " "; 18 | cout << endl; 19 | 20 | // from vector to vector 21 | vector dvc2(ivc.begin(), ivc.end()); 22 | for (auto i : ivc) cout << i << " "; 23 | cout << endl; 24 | for (auto d : dvc2) cout << d << " "; 25 | 26 | return 0; 27 | } -------------------------------------------------------------------------------- /ch09/exercise9_18.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::string; using std::deque; using std::cout; using std::cin; using std::endl; 6 | 7 | int main() 8 | { 9 | deque input; 10 | for (string str; cin >> str; input.push_back(str)); 11 | for (auto iter = input.cbegin(); iter != input.cend(); ++iter) 12 | cout << *iter << endl; 13 | 14 | return 0; 15 | } -------------------------------------------------------------------------------- /ch09/exercise9_20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using std::deque; using std::list; using std::cout; using std::cin; using std::endl; 5 | 6 | int main() 7 | { 8 | list l{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 9 | deque odd, even; 10 | for (auto i : l) 11 | (i & 0x1 ? odd : even).push_back(i); 12 | 13 | for (auto i : odd) cout << i << " "; 14 | cout << endl; 15 | for (auto i : even)cout << i << " "; 16 | cout << endl; 17 | 18 | return 0; 19 | } -------------------------------------------------------------------------------- /ch09/exercise9_24.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::vector v; 7 | std::cout << v.at(0); 8 | std::cout << v[0]; 9 | std::cout << v.front(); 10 | std::cout << *v.begin(); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /ch09/exercise9_27.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() 7 | { 8 | forward_list flst = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 9 | auto prev = flst.before_begin(); 10 | auto curr = flst.begin(); 11 | 12 | while (curr != flst.end()) 13 | { 14 | if (*curr & 0x1) 15 | { 16 | curr = flst.erase_after(prev); 17 | } 18 | else 19 | { 20 | prev = curr; 21 | ++curr; 22 | } 23 | } 24 | 25 | for (auto i : flst) 26 | { 27 | cout << i << endl; 28 | } 29 | 30 | return 0; 31 | } -------------------------------------------------------------------------------- /ch09/exercise9_33.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::vector; using std::cout; using std::endl; 5 | 6 | int main() 7 | { 8 | vector v{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 9 | auto begin = v.begin(); 10 | while (begin != v.end()) 11 | { 12 | ++begin; 13 | /*begin = */v.insert(begin, 42); 14 | ++begin; 15 | } 16 | 17 | for (auto i : v) 18 | cout << i << " "; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /ch09/exercise9_34.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::vector; using std::cout; using std::endl; 5 | 6 | int main() 7 | { 8 | vector vi{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 9 | int i = 0; 10 | auto iter = vi.begin(); 11 | while (iter != vi.end()) 12 | { 13 | if (*iter % 2) 14 | iter = vi.insert(iter, *iter); 15 | ++iter; 16 | cout << i++ << endl; 17 | } 18 | 19 | for (auto i : vi) 20 | cout << i << " "; 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /ch09/exercise9_38.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int main() 8 | { 9 | vector v; 10 | 11 | for (int i = 0; i < 100; i++) 12 | { 13 | cout << "capacity: " << v.capacity() << " size: " << v.size() << endl; 14 | v.push_back(i); 15 | } 16 | return 0; 17 | } -------------------------------------------------------------------------------- /ch09/exercise9_43.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | void replace(string& s, const string& oldVal, const string& newVal) 7 | { 8 | auto curr = s.begin(); 9 | while (curr != s.end() - oldVal.size()) 10 | { 11 | if (oldVal == string(curr, curr + oldVal.size())) 12 | { 13 | curr = s.erase(curr, curr + oldVal.size()); 14 | curr = s.insert(curr, newVal.begin(), newVal.end()); 15 | curr += newVal.size(); 16 | } 17 | else 18 | { 19 | ++curr; 20 | } 21 | } 22 | } 23 | 24 | int main() 25 | { 26 | string s("To drive straight thru is a foolish, tho courageous act."); 27 | replace(s,"tho","though"); 28 | replace(s, "thru", "through"); 29 | 30 | cout << s; 31 | } -------------------------------------------------------------------------------- /ch09/exercise9_44.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | void replace(string& s, const string& oldVal, const string& newVal) 7 | { 8 | for (size_t pos = 0; pos <= s.size() - oldVal.size(); /* */) 9 | { 10 | if (s[pos] == oldVal[0] && s.substr(pos, oldVal.size()) == oldVal) 11 | { 12 | s.replace(pos, oldVal.size(), newVal); 13 | pos += newVal.size(); 14 | } 15 | else 16 | { 17 | ++pos; 18 | } 19 | } 20 | 21 | } 22 | 23 | int main() 24 | { 25 | string s("To drive straight thru is a foolish, tho courageous act."); 26 | replace(s, "tho", "though"); 27 | replace(s, "thru", "through"); 28 | 29 | cout << s; 30 | } -------------------------------------------------------------------------------- /ch09/exercise9_45.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::string; 5 | using std::cin; 6 | using std::cout; 7 | using std::endl; 8 | 9 | string add_pre_and_suffix(string name, string const& pre, string const& su) 10 | { 11 | name.insert(name.begin(), pre.cbegin(), pre.cend()); 12 | return name.append(su); 13 | } 14 | 15 | int main() 16 | { 17 | string name("Huang"); 18 | cout << add_pre_and_suffix(name, "Mr.", " Jr.") << endl; 19 | return 0; 20 | } -------------------------------------------------------------------------------- /ch09/exercise9_46.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | std::string add_pre_and_suffix(std::string name, std::string const& pre, std::string const& su) 5 | { 6 | name.insert(0, pre); 7 | name.insert(name.size(), su); 8 | return name; 9 | } 10 | 11 | int main() 12 | { 13 | std::string name("Huang"); 14 | std::cout << add_pre_and_suffix(name, "Mr.", " Jr."); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /ch09/exercise9_47.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() 7 | { 8 | string numbers("0123456789"); 9 | string s("ab2c3d7R4E6"); 10 | 11 | cout << "numeric characters: "; 12 | for (int pos = 0; (pos = s.find_first_of(numbers, pos)) != string::npos; ++pos) 13 | { 14 | cout << s[pos] << " "; 15 | } 16 | 17 | cout << "\nalphabetic characters: "; 18 | for (int pos = 0; (pos = s.find_first_not_of(numbers, pos)) != string::npos; ++pos) 19 | { 20 | cout << s[pos] << " "; 21 | } 22 | 23 | return 0; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ch09/exercise9_49.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | void find_not_in(const string& s,string& result) 8 | { 9 | string not_in("dfpg"); 10 | int size; 11 | if (s.find_first_of(not_in) == string::npos) 12 | { 13 | result = result.size() < s.size() ? s : result; 14 | } 15 | } 16 | 17 | int main() 18 | { 19 | ifstream ifs("H:/code/C++/Cpp_Primer_Answers/data/letter.txt"); 20 | if (!ifs) 21 | return -1; 22 | 23 | string longest; 24 | 25 | for (string curr; ifs >> curr; ) 26 | { 27 | find_not_in(curr, longest); 28 | } 29 | cout << longest << endl; 30 | return 0; 31 | } -------------------------------------------------------------------------------- /ch09/exercise9_50.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int sum_of_int(const vector& v) 8 | { 9 | int sum = 0; 10 | for (auto i : v) 11 | { 12 | sum += stoi(i); 13 | } 14 | return sum; 15 | } 16 | 17 | float sum_of_float(const vector& v) 18 | { 19 | float sum = 0; 20 | for (auto i : v) 21 | { 22 | sum += stof(i); 23 | } 24 | return sum; 25 | } 26 | 27 | int main() 28 | { 29 | vector v = { "1", "2", "3", "4.5" }; 30 | cout << sum_of_int(v) << endl; 31 | cout << sum_of_float(v) << endl; 32 | return 0; 33 | } -------------------------------------------------------------------------------- /ch09/exercise9_51.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | class date 8 | { 9 | private: 10 | unsigned year, month, day; 11 | 12 | public: 13 | date(const string& s) 14 | { 15 | if (s.find_first_of("/") != string::npos) 16 | convert1(s); 17 | else if (s.find_first_of(",") != string::npos) 18 | convert2(s); 19 | else if (s.find_first_of(" ") != string::npos) 20 | convert3(s); 21 | else 22 | year = 1900, month = 1, day = 1; 23 | } 24 | 25 | void print() 26 | { 27 | cout << "day:" << day << " " << "month: " << month << " " << "year: " << year << endl; 28 | } 29 | 30 | private: 31 | void convert1(const string& s) 32 | { 33 | day = stoi(s.substr(0, s.find_first_of("/"))); 34 | month = stoi(s.substr(s.find_first_of("/") + 1, s.find_last_of("/") - s.find_first_of("/"))); 35 | year = stoi(s.substr(s.find_last_of("/") + 1, 4)); 36 | } 37 | void convert2(const string& s) 38 | { 39 | convert_month(s); 40 | day = stoi(s.substr(s.find_first_of("123456789"), s.find_first_of(",") - s.find_first_of("123456789"))); 41 | year = stoi(s.substr(s.find_last_of(',') + 1, 4)); 42 | } 43 | void convert3(const string& s) 44 | { 45 | convert_month(s); 46 | day = stoi(s.substr(s.find_first_of("123456789"), s.find_first_of(" ") - s.find_first_of("123456789"))); 47 | year = stoi(s.substr(s.find_last_of(' ') + 1, 4)); 48 | } 49 | 50 | void convert_month(const string& s) 51 | { 52 | if (s.find("Jan") < s.size()) month = 1; 53 | if (s.find("Feb") < s.size()) month = 2; 54 | if (s.find("Mar") < s.size()) month = 3; 55 | if (s.find("Apr") < s.size()) month = 4; 56 | if (s.find("May") < s.size()) month = 5; 57 | if (s.find("Jun") < s.size()) month = 6; 58 | if (s.find("Jul") < s.size()) month = 7; 59 | if (s.find("Aug") < s.size()) month = 8; 60 | if (s.find("Sep") < s.size()) month = 9; 61 | if (s.find("Oct") < s.size()) month = 10; 62 | if (s.find("Nov") < s.size()) month = 11; 63 | if (s.find("Dec") < s.size()) month = 12; 64 | } 65 | }; 66 | 67 | int main() 68 | { 69 | date d1("9/5/1990"); 70 | date d2("January 7,1970"); 71 | date d3("Jan 11 1942"); 72 | 73 | d1.print(); 74 | d2.print(); 75 | d3.print(); 76 | 77 | return 0; 78 | } 79 | 80 | -------------------------------------------------------------------------------- /ch09/exercise9_52.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | string calc(string l, string r, string op) 9 | { 10 | string s; 11 | if (op == "-") 12 | s = to_string(stoi(l) - stoi(r)); 13 | return s; 14 | } 15 | 16 | int main() 17 | { 18 | string s("1+2*(7-4)"); 19 | stack stack; 20 | for (auto iter = s.begin(); iter != s.end();) 21 | { 22 | if (*iter == '(') 23 | { 24 | stack.push(string(1, *iter)); 25 | ++iter; 26 | while (*iter != ')') 27 | { 28 | stack.push(string(1, *iter)); 29 | ++iter; 30 | } 31 | } 32 | else if (*iter == ')') 33 | { 34 | string r = stack.top(); stack.pop(); 35 | string op = stack.top(); stack.pop(); 36 | string l = stack.top(); stack.pop(); 37 | stack.pop(); // '(' 弹出 38 | stack.push(calc(l, r, op)); 39 | ++iter; 40 | } 41 | else 42 | { 43 | ++iter; 44 | } 45 | 46 | } 47 | 48 | while (!stack.empty()) 49 | { 50 | cout << stack.top() << endl; 51 | stack.pop(); 52 | } 53 | return 0; 54 | } -------------------------------------------------------------------------------- /ch10/exercise10_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | int main() 8 | { 9 | std::vector v = { 1, 2, 3, 4, 5, 6, 6, 6, 2 }; 10 | std::cout << std::count(v.cbegin(), v.cend(), 6) << std::endl; 11 | 12 | return 0; 13 | } -------------------------------------------------------------------------------- /ch10/exercise10_11.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | template 9 | inline std::ostream& println(Sequence const& seq) 10 | { 11 | for (auto const& elem : seq) std::cout << elem << " "; 12 | std::cout << std::endl; 13 | 14 | return std::cout; 15 | } 16 | 17 | inline bool 18 | is_shorter(std::string const& lhs, std::string const& rhs) 19 | { 20 | return lhs.size() < rhs.size(); 21 | } 22 | 23 | 24 | void elimdups(std::vector &vs) 25 | { 26 | std::sort(vs.begin(), vs.end()); 27 | auto new_end = std::unique(vs.begin(), vs.end()); 28 | vs.erase(new_end, vs.end()); 29 | } 30 | 31 | 32 | int main() 33 | { 34 | std::vector v{ 35 | "1234", "1234", "1234", "Hi", "alan", "wang" 36 | }; 37 | elimdups(v); 38 | std::stable_sort(v.begin(), v.end(), is_shorter); 39 | std::cout << "ex10.11 :\n"; 40 | println(v); 41 | 42 | return 0; 43 | } -------------------------------------------------------------------------------- /ch10/exercise10_12.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "exercise7_26.h" 8 | 9 | inline bool compareIsbn(const Sales_data &sd1, const Sales_data &sd2) 10 | { 11 | return sd1.isbn().size() < sd2.isbn().size(); 12 | } 13 | 14 | int main() 15 | { 16 | Sales_data d1("aa"), d2("aaaa"), d3("aaa"), d4("z"), d5("aaaaz"); 17 | std::vector v{ d1, d2, d3, d4, d5 }; 18 | 19 | std::sort(v.begin(), v.end(), compareIsbn); 20 | 21 | for (const auto &element : v) 22 | std::cout << element.isbn() << " "; 23 | std::cout << std::endl; 24 | 25 | return 0; 26 | } -------------------------------------------------------------------------------- /ch10/exercise10_13.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | bool predicate(const std::string &s) 7 | { 8 | return s.size() >= 5; 9 | } 10 | 11 | int main() 12 | { 13 | auto v = std::vector{ "a", "as", "aasss", "aaaaassaa", "aaaaaabba", "aaa" }; 14 | auto pivot = std::partition(v.begin(), v.end(), predicate); 15 | 16 | for (auto it = v.cbegin(); it != pivot; ++it) 17 | std::cout << *it << " "; 18 | std::cout << std::endl; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /ch10/exercise10_16.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | void elimdups(std::vector &vs) 9 | { 10 | std::sort(vs.begin(), vs.end()); 11 | auto new_end = std::unique(vs.begin(), vs.end()); 12 | vs.erase(new_end, vs.end()); 13 | } 14 | 15 | void biggies(std::vector &vs, std::size_t sz) 16 | { 17 | 18 | elimdups(vs); 19 | 20 | std::stable_sort(vs.begin(), vs.end(), 21 | [](string const& lhs, string const& rhs) { 22 | return lhs.size() < rhs.size(); } 23 | ); 24 | 25 | auto wc = std::find_if(vs.begin(), vs.end(), 26 | [sz](string const& s) { return s.size() >= sz; } 27 | ); 28 | 29 | std::for_each(wc, vs.end(), 30 | [](const string &s) { 31 | std::cout << s << " "; } 32 | ); 33 | } 34 | 35 | int main() 36 | { 37 | std::vector v 38 | { 39 | "1234", "1234", "1234", "hi~", "alan", "alan", "cp" 40 | }; 41 | std::cout << "ex10.16: "; 42 | biggies(v, 3); 43 | std::cout << std::endl; 44 | 45 | return 0; 46 | } -------------------------------------------------------------------------------- /ch10/exercise10_17.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "exercise7_26.h" 6 | 7 | int main() 8 | { 9 | Sales_data d1("aa"), d2("aaaa"), d3("aaa"), d4("z"), d5("aaaaz"); 10 | std::vector v{ d1, d2, d3, d4, d5 }; 11 | 12 | std::sort(v.begin(), v.end(), 13 | [](const Sales_data &sd1, const Sales_data &sd2) { 14 | return sd1.isbn().size() < sd2.isbn().size(); } 15 | ); 16 | 17 | for (const auto &element : v) 18 | std::cout << element.isbn() << " "; 19 | std::cout << std::endl; 20 | 21 | return 0; 22 | } -------------------------------------------------------------------------------- /ch10/exercise10_18.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void elimdups(std::vector &vs) 7 | { 8 | std::sort(vs.begin(), vs.end()); 9 | auto new_end = std::unique(vs.begin(), vs.end()); 10 | vs.erase(new_end, vs.end()); 11 | } 12 | 13 | void biggies_partition(std::vector &vs, std::size_t sz) 14 | { 15 | elimdups(vs); 16 | 17 | auto pivot = partition(vs.begin(), vs.end(), 18 | [sz](const std::string &s) { 19 | return s.size() >= sz; } 20 | ); 21 | 22 | for (auto it = vs.cbegin(); it != pivot; ++it) 23 | std::cout << *it << " "; 24 | } 25 | 26 | int main() 27 | { 28 | std::vector v{ "the", "quick", "red", "fox", "jumps", 29 | "over", "the", "slow", "red", "turtle" }; 30 | 31 | std::cout << "ex10.18: "; 32 | biggies_partition(v, 4); 33 | std::cout << std::endl; 34 | return 0; 35 | } -------------------------------------------------------------------------------- /ch10/exercise10_19.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void elimdups(std::vector &vs) 7 | { 8 | std::sort(vs.begin(), vs.end()); 9 | auto new_end = std::unique(vs.begin(), vs.end()); 10 | vs.erase(new_end, vs.end()); 11 | } 12 | 13 | void biggies_stable_partition(std::vector &vs, std::size_t sz) 14 | { 15 | elimdups(vs); 16 | 17 | auto pivot = stable_partition(vs.begin(), vs.end(), [sz](const std::string& s) 18 | { 19 | return s.size() >= sz; 20 | }); 21 | 22 | for (auto it = vs.cbegin(); it != pivot; ++it) 23 | std::cout << *it << " "; 24 | } 25 | 26 | 27 | int main() 28 | { 29 | std::vector v{ "the", "quick", "red", "fox", "jumps", 30 | "over", "the", "slow", "red", "turtle"}; 31 | 32 | biggies_stable_partition(v, 4); 33 | std::cout << std::endl; 34 | 35 | return 0; 36 | } -------------------------------------------------------------------------------- /ch10/exercise10_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | int main() 8 | { 9 | std::list l = { "aa", "aaa", "aa", "cc" }; 10 | std::cout << std::count(l.cbegin(), l.cend(), "aa") << std::endl; 11 | 12 | return 0; 13 | } -------------------------------------------------------------------------------- /ch10/exercise10_20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | size_t bigerThan6(vector const& v) 9 | { 10 | return count_if(v.cbegin(), v.cend(), 11 | [](string const& s) { return s.size() > 6; } 12 | ); 13 | } 14 | 15 | int main() 16 | { 17 | vector v{ "1234", "123456", "1234567", "1234567", "1234567", "1234567" }; 18 | std::cout << "ex10.20: " << bigerThan6(v) << std::endl; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /ch10/exercise10_22.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using std::string; 8 | using namespace std::placeholders; 9 | 10 | bool isLesserThanOrEqualTo6(const string &s, string::size_type sz) 11 | { 12 | return s.size() <= sz; 13 | } 14 | 15 | int main() 16 | { 17 | std::vector authors{ "1234567", "1234", "1234567890", "1234567", "12345" }; 18 | std::cout << count_if(authors.cbegin(), authors.cend(), bind(isLesserThanOrEqualTo6, _1, 6)) << std::endl; 19 | } -------------------------------------------------------------------------------- /ch10/exercise10_24.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | using namespace std::placeholders; 9 | 10 | bool check_size(const string& s, size_t i) 11 | { 12 | return i > s.size(); 13 | } 14 | 15 | int main() 16 | { 17 | vector v = { 1, 2, 3, 4, 5, 6, 7 }; 18 | string s("12345"); 19 | 20 | auto it = find_if(v.cbegin(), v.cend(), bind(check_size, s, _1)); 21 | if (it != v.end()) 22 | cout << *it << endl; 23 | } -------------------------------------------------------------------------------- /ch10/exercise10_25.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using std::string; using std::vector; 8 | using namespace std::placeholders; 9 | 10 | void elimdups(vector &vs) 11 | { 12 | std::sort(vs.begin(), vs.end()); 13 | vs.erase(unique(vs.begin(), vs.end()), vs.end()); 14 | } 15 | 16 | bool check_size(const string &s, string::size_type sz) 17 | { 18 | return s.size() >= sz; 19 | } 20 | 21 | void biggies(vector &words, vector::size_type sz) 22 | { 23 | elimdups(words); 24 | auto iter = std::stable_partition(words.begin(), words.end(), bind(check_size, _1, sz)); 25 | for_each(words.begin(), iter, [](const string &s) { std::cout << s << " "; }); 26 | } 27 | 28 | int main() 29 | { 30 | std::vector v{ "the", "quick", "red", "fox", "jumps", 31 | "over", "the", "slow", "red", "turtle" }; 32 | biggies(v, 4); 33 | 34 | return 0; 35 | } -------------------------------------------------------------------------------- /ch10/exercise10_27.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main() 8 | { 9 | std::vector vec{ 1, 1, 3, 3, 5, 5, 7, 7, 9 }; 10 | std::list lst; 11 | 12 | std::unique_copy(vec.begin(), vec.end(), back_inserter(lst)); 13 | for (auto i : lst) 14 | std::cout << i << " "; 15 | std::cout << std::endl; 16 | return 0; 17 | } -------------------------------------------------------------------------------- /ch10/exercise10_28.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using std::list; using std::copy; using std::cout; using std::endl; 8 | 9 | template 10 | void print(Sequence const& seq) 11 | { 12 | for (const auto& i : seq) 13 | std::cout << i << " "; 14 | std::cout << std::endl; 15 | } 16 | 17 | int main() 18 | { 19 | std::vector vec{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 20 | 21 | // inserter 22 | list lst1; 23 | copy(vec.cbegin(), vec.cend(), inserter(lst1, lst1.begin())); 24 | print(lst1); 25 | 26 | // back_inserter 27 | list lit2; 28 | copy(vec.cbegin(), vec.cend(), back_inserter(lit2)); 29 | print(lit2); 30 | 31 | // front_inserter 32 | list lst3; 33 | copy(vec.cbegin(), vec.cend(), front_inserter(lst3)); 34 | print(lst3); 35 | 36 | return 0; 37 | } -------------------------------------------------------------------------------- /ch10/exercise10_29.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using std::string; 8 | 9 | int main() 10 | { 11 | std::ifstream ifs("H:/code/C++/Cpp_Primer_Answers/data/books.txt"); 12 | std::istream_iterator in(ifs), eof; 13 | std::vector vec; 14 | std::copy(in, eof, back_inserter(vec)); 15 | 16 | std::copy(vec.cbegin(), vec.cend(), std::ostream_iterator(std::cout, "\n")); 17 | return 0; 18 | } -------------------------------------------------------------------------------- /ch10/exercise10_3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::vector v = { 1, 2, 3, 4 }; 8 | std::cout << std::accumulate(v.cbegin(), v.cend(), 0) << std::endl; 9 | 10 | return 0; 11 | } -------------------------------------------------------------------------------- /ch10/exercise10_30.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | int main() 9 | { 10 | vector v; 11 | istream_iterator int_it(cin), int_eof; 12 | 13 | copy(int_it, int_eof, back_inserter(v)); 14 | sort(v.begin(), v.end()); 15 | 16 | copy(v.begin(), v.end(), ostream_iterator(cout," ")); 17 | cout << endl; 18 | return 0; 19 | } -------------------------------------------------------------------------------- /ch10/exercise10_31.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | int main() 9 | { 10 | vector v; 11 | istream_iterator int_it(cin), int_eof; 12 | 13 | unique_copy(int_it, int_eof, back_inserter(v)); 14 | sort(v.begin(), v.end()); 15 | 16 | copy(v.begin(), v.end(), ostream_iterator(cout, " ")); 17 | cout << endl; 18 | return 0; 19 | } -------------------------------------------------------------------------------- /ch10/exercise10_32.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "Sales_item.h" 7 | 8 | int main() 9 | { 10 | std::istream_iterator in_iter(std::cin), in_eof; 11 | std::vector vec; 12 | 13 | while (in_iter != in_eof) 14 | vec.push_back(*in_iter++); 15 | sort(vec.begin(), vec.end(), compareIsbn); 16 | for (auto beg = vec.cbegin(), end = beg; beg != vec.cend(); beg = end) 17 | { 18 | end = find_if(beg, vec.cend(), [beg](const Sales_item &item) { return item.isbn() != beg->isbn(); }); 19 | std::cout << std::accumulate(beg, end, Sales_item(beg->isbn())) << std::endl; 20 | } 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /ch10/exercise10_33.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char **argv) 6 | { 7 | if (argc != 4) return -1; 8 | 9 | std::ifstream ifs(argv[1]); 10 | std::ofstream ofs_odd(argv[2]), ofs_even(argv[3]); 11 | 12 | std::istream_iterator in(ifs), in_eof; 13 | std::ostream_iterator out_odd(ofs_odd, " "), out_even(ofs_even, "\n"); 14 | 15 | std::for_each(in, in_eof, [&out_odd, &out_even](const int i) 16 | { 17 | *(i & 0x1 ? out_odd : out_even)++ = i; 18 | }); 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /ch10/exercise10_34.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() 7 | { 8 | vector v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 9 | for (auto it = v.crbegin(); it != v.crend(); ++it) 10 | { 11 | cout << *it << endl; 12 | } 13 | 14 | return 0; 15 | } -------------------------------------------------------------------------------- /ch10/exercise10_35.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() 7 | { 8 | vector v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 9 | for (auto it = std::prev(v.cend()); true; --it) 10 | { 11 | std::cout << *it << " "; 12 | if (it == v.cbegin()) break; 13 | } 14 | std::cout << std::endl; 15 | 16 | return 0; 17 | } -------------------------------------------------------------------------------- /ch10/exercise10_36.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int main() 8 | { 9 | list l = { 1, 2, 0, 4, 5, 6, 7, 0, 9 }; 10 | auto it = find(l.crbegin(), l.crend(), 0); 11 | 12 | cout << distance(it, l.crend()) << endl; 13 | return 0; 14 | } -------------------------------------------------------------------------------- /ch10/exercise10_37.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | int main() 10 | { 11 | vector v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 12 | list l; 13 | 14 | copy(v.crbegin() + 3, v.crbegin() + 8, back_inserter(l)); 15 | 16 | for (auto i : l) std::cout << i << " "; 17 | cout << endl; 18 | return 0; 19 | } -------------------------------------------------------------------------------- /ch10/exercise10_4.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::vector vd = { 1.1, 0.5, 3.3 }; 8 | std::cout << "ex 10.04: " 9 | << std::accumulate(vd.cbegin(), vd.cend(), 0) 10 | << std::endl; 11 | 12 | return 0; 13 | } -------------------------------------------------------------------------------- /ch10/exercise10_42.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::string; using std::list; 6 | 7 | void elimDups(list &words) 8 | { 9 | words.sort(); 10 | words.unique(); 11 | } 12 | 13 | int main() 14 | { 15 | list l = { "aa", "aa", "aa", "aa", "aasss", "aa" }; 16 | elimDups(l); 17 | for (const auto& e : l) 18 | std::cout << e << " "; 19 | std::cout << std::endl; 20 | } -------------------------------------------------------------------------------- /ch10/exercise10_6.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::vector; using std::cout; using std::endl; using std::fill_n; 6 | 7 | int main() 8 | { 9 | vector vec{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 10 | fill_n(vec.begin(), vec.size(), 0); 11 | 12 | for (auto i : vec) 13 | cout << i << " "; 14 | cout << endl; 15 | } -------------------------------------------------------------------------------- /ch10/exercise10_9.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | template 7 | auto println(Sequence const& seq) -> std::ostream& 8 | { 9 | for (auto const& elem : seq) 10 | std::cout << elem << " "; 11 | return std::cout << std::endl; 12 | } 13 | 14 | auto eliminate_duplicates(std::vector &vs) -> std::vector& 15 | { 16 | std::sort(vs.begin(), vs.end()); 17 | println(vs); 18 | 19 | auto new_end = std::unique(vs.begin(), vs.end()); 20 | println(vs); 21 | 22 | vs.erase(new_end, vs.end()); 23 | return vs; 24 | } 25 | 26 | int main() 27 | { 28 | std::vector vs{ "a", "v", "a", "s", "v", "a", "a" }; 29 | println(vs); 30 | println(eliminate_duplicates(vs)); 31 | 32 | return 0; 33 | } -------------------------------------------------------------------------------- /ch10/exercise7_26.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_26_h 2 | #define CP5_ex7_26_h 3 | 4 | #include 5 | #include 6 | 7 | class Sales_data 8 | { 9 | friend std::istream &read(std::istream &is, Sales_data &item); 10 | friend std::ostream &print(std::ostream &os, const Sales_data &item); 11 | friend Sales_data add(const Sales_data &lhs, const Sales_data &rhs); 12 | 13 | public: 14 | Sales_data() = default; 15 | Sales_data(const std::string &s) :bookNo(s) {} 16 | Sales_data(const std::string &s, unsigned n, double p) :bookNo(s), units_sold(n), revenue(n*p) {} 17 | Sales_data(std::istream &is) { read(is, *this); } 18 | 19 | std::string isbn() const { return bookNo; }; 20 | Sales_data& combine(const Sales_data&); 21 | 22 | private: 23 | inline double avg_price() const; 24 | 25 | private: 26 | std::string bookNo; 27 | unsigned units_sold = 0; 28 | double revenue = 0.0; 29 | }; 30 | 31 | inline 32 | double Sales_data::avg_price() const 33 | { 34 | return units_sold ? revenue / units_sold : 0; 35 | } 36 | 37 | std::istream &read(std::istream &is, Sales_data &item); 38 | std::ostream &print(std::ostream &os, const Sales_data &item); 39 | Sales_data add(const Sales_data &lhs, const Sales_data &rhs); 40 | 41 | #endif -------------------------------------------------------------------------------- /ch11/exercise11_12.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | std::vector> vec; 9 | std::string str; 10 | int i; 11 | while (std::cin >> str >> i) 12 | vec.push_back(std::pair(str, i)); 13 | 14 | for (const auto &p : vec) 15 | std::cout << p.first << ":" << p.second << std::endl; 16 | } -------------------------------------------------------------------------------- /ch11/exercise11_14.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using std::ostream; 7 | using std::cout; 8 | using std::cin; 9 | using std::endl; 10 | using std::string; 11 | using std::make_pair; 12 | using std::pair; 13 | using std::vector; 14 | using std::map; 15 | 16 | class Families 17 | { 18 | public: 19 | using Child = pair; 20 | using Children = vector; 21 | using Data = map; 22 | 23 | void add(string const& last_name, string const& first_name, string birthday) 24 | { 25 | auto child = make_pair(first_name, birthday); 26 | _data[last_name].push_back(child); 27 | } 28 | 29 | void print() const 30 | { 31 | for (auto const& pair : _data) 32 | { 33 | cout << pair.first << ":\n"; 34 | for (auto const& child : pair.second) 35 | cout << child.first << " " << child.second << endl; 36 | cout << endl; 37 | } 38 | } 39 | 40 | private: 41 | Data _data; 42 | }; 43 | 44 | int main() 45 | { 46 | Families families; 47 | auto msg = "Please enter last name, first name and birthday:\n"; 48 | for (string l, f, b; cout << msg, cin >> l >> f >> b; families.add(l, f, b)); 49 | families.print(); 50 | 51 | return 0; 52 | } -------------------------------------------------------------------------------- /ch11/exercise11_20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::string; 6 | using std::map; 7 | using std::cin; 8 | using std::cout; 9 | 10 | int main() 11 | { 12 | map counts; 13 | for (string word; cin >> word;) 14 | { 15 | auto result = counts.insert({ word, 1 }); 16 | if (!result.second) 17 | ++result.first->second; 18 | } 19 | for (auto const& count : counts) 20 | cout << count.first << " " << count.second << ((count.second > 1) ? " times\n" : " time\n"); 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /ch11/exercise11_23.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::string; 6 | using std::multimap; 7 | using std::cin; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | multimap families; 13 | for (string lname, cname; cin >> cname >> lname; families.emplace(lname, cname)); 14 | for (auto const& family : families) 15 | std::cout << family.second << " " << family.first << endl; 16 | } -------------------------------------------------------------------------------- /ch11/exercise11_3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main() 8 | { 9 | std::map word_count; 10 | std::string word; 11 | while (std::cin >> word) 12 | ++word_count[word]; 13 | 14 | for (const auto& elem : word_count) 15 | std::cout << elem.first << " : " << elem.second << "\n"; 16 | return 0; 17 | } -------------------------------------------------------------------------------- /ch11/exercise11_31.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::string; 6 | 7 | int main() 8 | { 9 | std::multimap authors{ 10 | { "alan", "DMA" }, 11 | { "pezy", "LeetCode" }, 12 | { "alan", "CLRS" }, 13 | { "wang", "FTP" }, 14 | { "pezy", "CP5" }, 15 | { "wang", "CPP-Concurrency" } }; 16 | 17 | string author = "pezy"; 18 | string work = "CP5"; 19 | 20 | auto found = authors.find(author); 21 | auto count = authors.count(author); 22 | while (count) 23 | { 24 | if (found->second == work) 25 | { 26 | authors.erase(found); 27 | break; 28 | } 29 | ++found; 30 | --count; 31 | } 32 | 33 | for (const auto &author : authors) 34 | std::cout << author.first << " " << author.second << std::endl; 35 | 36 | return 0; 37 | } -------------------------------------------------------------------------------- /ch11/exercise11_32.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using std::string; 7 | 8 | int main() 9 | { 10 | std::multimap authors{ 11 | { "alan", "DMA" }, 12 | { "pezy", "LeetCode" }, 13 | { "alan", "CLRS" }, 14 | { "wang", "FTP" }, 15 | { "pezy", "CP5" }, 16 | { "wang", "CPP-Concurrency" } }; 17 | std::map> order_authors; 18 | 19 | for (const auto &author : authors) 20 | order_authors[author.first].insert(author.second); 21 | 22 | for (const auto &author : order_authors) 23 | { 24 | std::cout << author.first << ": "; 25 | for (const auto &work : author.second) 26 | std::cout << work << " "; 27 | std::cout << std::endl; 28 | } 29 | 30 | return 0; 31 | } -------------------------------------------------------------------------------- /ch11/exercise11_33.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | void word_transform(ifstream&, ifstream&); 9 | map buildMap(ifstream&); 10 | string transform(const string&, map&); 11 | 12 | int main() 13 | { 14 | ifstream ifs_rules("H:/code/C++/Cpp_Primer_Answers/data/transform_rules.txt"); 15 | ifstream ifs_txt("H:/code/C++/Cpp_Primer_Answers/data/for_transform.txt"); 16 | 17 | word_transform(ifs_rules, ifs_txt); 18 | return 0; 19 | } 20 | 21 | void word_transform(ifstream& rule_file, ifstream& input) 22 | { 23 | auto rule_map = buildMap(rule_file); 24 | string text; 25 | while (getline(input, text)) 26 | { 27 | istringstream stream(text); 28 | string word; 29 | bool firstword = true; 30 | while (stream >> word) 31 | { 32 | if (firstword) 33 | firstword = false; 34 | else 35 | cout << " "; 36 | cout << transform(word, rule_map); 37 | } 38 | cout << endl; 39 | } 40 | } 41 | 42 | map buildMap(ifstream& rule_file) 43 | { 44 | map m; 45 | string key; 46 | string value; 47 | while (rule_file >> key && getline(rule_file, value)) 48 | { 49 | if (value.size() > 1) 50 | m[key] = value.substr(1); 51 | else 52 | throw runtime_error("no rule for " + key); 53 | } 54 | return m; 55 | } 56 | 57 | string transform(const string& s, map& m) 58 | { 59 | auto it = m.find(s); 60 | if (it != m.cend()) 61 | return it->second; 62 | else 63 | return s; 64 | } -------------------------------------------------------------------------------- /ch11/exercise11_38.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | void word_transform(ifstream&, ifstream&); 9 | unordered_map buildMap(ifstream&); 10 | string transform(const string&, unordered_map&); 11 | 12 | int main() 13 | { 14 | ifstream ifs_rules("H:/code/C++/Cpp_Primer_Answers/data/transform_rules.txt"); 15 | ifstream ifs_txt("H:/code/C++/Cpp_Primer_Answers/data/for_transform.txt"); 16 | 17 | word_transform(ifs_rules, ifs_txt); 18 | return 0; 19 | } 20 | 21 | void word_transform(ifstream& rule_file, ifstream& input) 22 | { 23 | auto rule_map = buildMap(rule_file); 24 | string text; 25 | while (getline(input, text)) 26 | { 27 | istringstream stream(text); 28 | string word; 29 | bool firstword = true; 30 | while (stream >> word) 31 | { 32 | if (firstword) 33 | firstword = false; 34 | else 35 | cout << " "; 36 | cout << transform(word, rule_map); 37 | } 38 | cout << endl; 39 | } 40 | } 41 | 42 | unordered_map buildMap(ifstream& rule_file) 43 | { 44 | unordered_map m; 45 | string key; 46 | string value; 47 | while (rule_file >> key && getline(rule_file, value)) 48 | { 49 | if (value.size() > 1) 50 | m[key] = value.substr(1); 51 | else 52 | throw runtime_error("no rule for " + key); 53 | } 54 | return m; 55 | } 56 | 57 | string transform(const string& s, unordered_map& m) 58 | { 59 | auto it = m.find(s); 60 | if (it != m.cend()) 61 | return it->second; 62 | else 63 | return s; 64 | } -------------------------------------------------------------------------------- /ch11/exercise11_4.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void word_count_pro(std::map& m) 8 | { 9 | std::string word; 10 | while (std::cin >> word) 11 | { 12 | for (auto& ch : word) 13 | ch = tolower(ch); 14 | 15 | word.erase(std::remove_if(word.begin(), word.end(), ispunct), 16 | word.end()); 17 | ++m[word]; 18 | } 19 | for (const auto& e : m) std::cout << e.first << " : " << e.second << "\n"; 20 | } 21 | 22 | int main() 23 | { 24 | std::map m; 25 | word_count_pro(m); 26 | 27 | return 0; 28 | } -------------------------------------------------------------------------------- /ch11/exercise11_8.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | std::vector exclude = { "aa", "bb", "cc", "dd", "ee", "ff" }; 9 | for (std::string word; std::cout << "Enter plz:\n", std::cin >> word;) 10 | { 11 | auto is_excluded = std::binary_search(exclude.cbegin(), exclude.cend(), word); 12 | auto reply = is_excluded ? "excluded" : "not excluded"; 13 | std::cout << reply << std::endl; 14 | } 15 | 16 | return 0; 17 | } -------------------------------------------------------------------------------- /ch12/exercise12_14.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct connection 6 | { 7 | std::string ip; 8 | int port; 9 | connection(std::string i, int p) : ip(i), port(p) {} 10 | }; 11 | 12 | struct destination 13 | { 14 | std::string ip; 15 | int port; 16 | destination(std::string i, int p) : ip(i), port(p) {} 17 | }; 18 | 19 | connection connect(destination* pDest) 20 | { 21 | std::shared_ptr pConn(new connection(pDest->ip, pDest->port)); 22 | std::cout << "creating connection(" << pConn.use_count() << ")" << std::endl; 23 | return *pConn; 24 | } 25 | 26 | void disconnect(connection pConn) 27 | { 28 | std::cout << "connection close(" << pConn.ip << ":" << pConn.port << ")" << std::endl; 29 | } 30 | 31 | void end_connection(connection* pConn) 32 | { 33 | disconnect(*pConn); 34 | } 35 | 36 | void f(destination &d) 37 | { 38 | connection conn = connect(&d); 39 | std::shared_ptr p(&conn, end_connection); 40 | std::cout << "connecting now(" << p.use_count() << ")" << std::endl; 41 | } 42 | 43 | int main() 44 | { 45 | destination dest("220.181.111.111", 10086); 46 | f(dest); 47 | 48 | return 0; 49 | } -------------------------------------------------------------------------------- /ch12/exercise12_15.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct connection 6 | { 7 | std::string ip; 8 | int port; 9 | connection(std::string i, int p) : ip(i), port(p) {} 10 | }; 11 | 12 | struct destination 13 | { 14 | std::string ip; 15 | int port; 16 | destination(std::string i, int p) : ip(i), port(p) {} 17 | }; 18 | 19 | connection connect(destination* pDest) 20 | { 21 | std::shared_ptr pConn(new connection(pDest->ip, pDest->port)); 22 | std::cout << "creating connection(" << pConn.use_count() << ")" << std::endl; 23 | return *pConn; 24 | } 25 | 26 | void disconnect(connection pConn) 27 | { 28 | std::cout << "connection close(" << pConn.ip << ":" << pConn.port << ")" << std::endl; 29 | } 30 | 31 | void f(destination &d) 32 | { 33 | connection conn = connect(&d); 34 | std::shared_ptr p(&conn, [] (connection* p){ disconnect(*p); }); 35 | std::cout << "connecting now(" << p.use_count() << ")" << std::endl; 36 | } 37 | 38 | int main() 39 | { 40 | destination dest("220.181.111.111", 10086); 41 | f(dest); 42 | 43 | return 0; 44 | } -------------------------------------------------------------------------------- /ch12/exercise12_16.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangmingchuan/Cpp_Primer_Answers/925506ca53f7b2e8501bc8eaaee3dba8c03d9ec2/ch12/exercise12_16.cpp -------------------------------------------------------------------------------- /ch12/exercise12_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "exercise12_2.h" 3 | 4 | int main() 5 | { 6 | StrBlob sb{ "hello", "world" }; 7 | const StrBlob csb{ "const", "hello", "world", "aaa" }; 8 | 9 | std::cout << "sb : " << sb.front() << " " << sb.back() << std::endl; 10 | std::cout << "csb : " << csb.front() << " " << csb.back() << std::endl; 11 | 12 | return 0; 13 | } -------------------------------------------------------------------------------- /ch12/exercise12_2.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using std::vector; using std::string; 8 | 9 | class StrBlob 10 | { 11 | public: 12 | using size_type = vector::size_type; 13 | 14 | StrBlob() :data(std::make_shared>()) {} 15 | StrBlob(std::initializer_list il) : data(std::make_shared>(il)) {} 16 | 17 | size_type size() const 18 | { 19 | return data->size(); 20 | } 21 | 22 | bool empty() const 23 | { 24 | return data->empty(); 25 | } 26 | 27 | void push_back(const string& s) const 28 | { 29 | data->push_back(s); 30 | } 31 | 32 | void pop_back() const 33 | { 34 | check(0, "pop_back on empty StrBlob"); 35 | data->pop_back(); 36 | } 37 | 38 | string& front() 39 | { 40 | check(0, "front on empty StrBlob"); 41 | return data->front(); 42 | } 43 | 44 | string& back() 45 | { 46 | check(0, "back on empty StrBlob"); 47 | return data->back(); 48 | } 49 | 50 | const string& front() const 51 | { 52 | check(0, "front on empty StrBlob"); 53 | return data->front(); 54 | } 55 | 56 | const string& back() const 57 | { 58 | check(0, "back on empty StrBlob"); 59 | return data->back(); 60 | } 61 | 62 | private: 63 | void check(size_type i, const string& msg) const 64 | { 65 | if (i >= data->size()) 66 | throw std::out_of_range(msg); 67 | } 68 | 69 | private: 70 | std::shared_ptr> data; 71 | }; -------------------------------------------------------------------------------- /ch12/exercise12_20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "exercise12_19.h" 4 | 5 | using namespace std; 6 | 7 | int main() 8 | { 9 | ifstream ifs("E:/code/cpp_primer_answer/Cpp_Primer_Answers/data/books.txt"); 10 | StrBlob sb; 11 | string s; 12 | while (getline(ifs, s)) 13 | { 14 | sb.push_back(s); 15 | } 16 | for (StrBlobPtr sbp = sb.begin(); sbp != sb.end(); sbp.incr()) 17 | { 18 | cout << sbp.deref() << endl; 19 | } 20 | 21 | return 0; 22 | } -------------------------------------------------------------------------------- /ch12/exercise12_23.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() { 7 | const char *c1 = "Hello "; 8 | const char *c2 = "World"; 9 | unsigned len = strlen(c1) + strlen(c2) + 1; 10 | char *r = new char[len](); 11 | strcat_s(r, len, c1); 12 | strcat_s(r, len, c2); 13 | std::cout << r << std::endl; 14 | 15 | std::string s1 = "Hello "; 16 | std::string s2 = "World"; 17 | strcpy_s(r, len, (s1 + s2).c_str()); 18 | std::cout << r << std::endl; 19 | 20 | delete[] r; 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch12/exercise12_24.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | std::cout << "How long do you want the string? "; 6 | int size{ 0 }; 7 | std::cin >> size; 8 | char *input = new char[size + 1](); 9 | std::cin.ignore(); 10 | std::cout << "input the string: "; 11 | std::cin.get(input, size + 1); 12 | std::cout << input; 13 | delete[] input; 14 | 15 | return 0; 16 | } -------------------------------------------------------------------------------- /ch12/exercise12_26.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int main() 8 | { 9 | int n = 5; 10 | allocator alloc; 11 | auto p = alloc.allocate(n); 12 | string s; 13 | auto q = p; 14 | while (cin >> s && q != p + n) 15 | { 16 | alloc.construct(q++, s); 17 | } 18 | while (q != p) 19 | { 20 | std::cout << *--q << " "; 21 | alloc.destroy(q); 22 | } 23 | alloc.deallocate(p, n); 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch12/exercise12_27.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise12_27.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | TextQuery::TextQuery(ifstream& ifs) : file(new vector) 10 | { 11 | string text; 12 | while (getline(ifs, text)) 13 | { 14 | file->push_back(text); 15 | int n = file->size() - 1; 16 | istringstream line(text); 17 | string word; 18 | while (line >> word) 19 | { 20 | auto &lines = wm[word]; 21 | if (!lines) 22 | lines.reset(new set); 23 | lines->insert(n); 24 | } 25 | } 26 | } 27 | 28 | QueryResult TextQuery::query(const string& s) const 29 | { 30 | static shared_ptr> nodata(new set); 31 | auto loc = wm.find(s); 32 | if (loc == wm.end()) 33 | return QueryResult(s, nodata, file); 34 | else 35 | return QueryResult(s, loc->second, file); 36 | } 37 | 38 | std::ostream& print(std::ostream& os, const QueryResult& qr) 39 | { 40 | os << qr.sought << " occurs " << qr.lines->size() << " " 41 | << "time" << (qr.lines->size() > 1 ? "s" : "") << endl; 42 | for (auto num : *qr.lines) 43 | os << "\t(line " << num + 1 << ") " << *(qr.file->begin() + num) << endl; 44 | return os; 45 | } -------------------------------------------------------------------------------- /ch12/exercise12_27.h: -------------------------------------------------------------------------------- 1 | #ifndef EX12_27_H 2 | #define EX12_27_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class QueryResult; 12 | 13 | class TextQuery 14 | { 15 | public: 16 | using line_no = std::vector::size_type; 17 | TextQuery(std::ifstream&); 18 | QueryResult query(const std::string& s) const; 19 | 20 | private: 21 | std::shared_ptr> file; 22 | std::map>> wm; 23 | }; 24 | 25 | class QueryResult 26 | { 27 | public: 28 | friend std::ostream& print(std::ostream&, const QueryResult&); 29 | QueryResult(std::string s, 30 | std::shared_ptr> p, 31 | std::shared_ptr> f) : 32 | sought(s), lines(p), file(f) 33 | {} 34 | 35 | private: 36 | std::string sought; 37 | std::shared_ptr> lines; 38 | std::shared_ptr> file; 39 | }; 40 | 41 | std::ostream& print(std::ostream&, const QueryResult&); 42 | 43 | #endif -------------------------------------------------------------------------------- /ch12/exercise12_27_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "exercise12_27.h" 5 | 6 | using namespace std; 7 | 8 | void runQueries(ifstream& infile) 9 | { 10 | TextQuery tq(infile); 11 | while (true) 12 | { 13 | cout << "enter word to look for, or q to quit: "; 14 | string s; 15 | if (!(cin >> s) || s == "q") break; 16 | print(cout, tq.query(s)) << endl; 17 | } 18 | } 19 | 20 | int main() 21 | { 22 | ifstream ifs("H:/code/C++/Cpp_Primer_Answers/data/storyDataFile.txt"); 23 | runQueries(ifs); 24 | return 0; 25 | } -------------------------------------------------------------------------------- /ch12/exercise12_28.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::string; 3 | 4 | #include 5 | using std::vector; 6 | 7 | #include 8 | using std::shared_ptr; 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | int main() 18 | { 19 | std::ifstream file("H:/code/C++/Cpp_Primer_Answers/data/storyDataFile.txt"); 20 | vector input; 21 | std::map> dictionary; 22 | decltype(input.size()) lineNo{ 0 }; 23 | 24 | for (string line; std::getline(file, line); ++lineNo) 25 | { 26 | input.push_back(line); 27 | std::istringstream line_stream(line); 28 | for (string text, word; line_stream >> text; word.clear()) 29 | { 30 | std::remove_copy_if(text.begin(), text.end(), std::back_inserter(word), ispunct); 31 | dictionary[word].insert(lineNo); 32 | } 33 | } 34 | 35 | while (true) 36 | { 37 | std::cout << "enter word to look for, or q to quit: "; 38 | string s; 39 | if (!(std::cin >> s) || s == "q") break; 40 | auto found = dictionary.find(s); 41 | if (found != dictionary.end()) 42 | { 43 | std::cout << s << " occurs " << found->second.size() << (found->second.size() > 1 ? " times" : " time") << std::endl; 44 | for (auto i : found->second) 45 | std::cout << "\t(line " << i + 1 << ") " << input.at(i) << std::endl; 46 | } 47 | else std::cout << s << " occurs 0 time" << std::endl; 48 | } 49 | } -------------------------------------------------------------------------------- /ch12/exercise12_6.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::vector; 5 | 6 | vector* alloc_vector() 7 | { 8 | return new vector(); 9 | } 10 | 11 | void assign_vector(vector* p) 12 | { 13 | int i; 14 | while (std::cin >> i) 15 | { 16 | p->push_back(i); 17 | } 18 | } 19 | 20 | void print_vector(vector* p) 21 | { 22 | for (auto i : *p) 23 | { 24 | std::cout << i << std::endl; 25 | } 26 | } 27 | 28 | int main() 29 | { 30 | auto p = alloc_vector(); 31 | assign_vector(p); 32 | print_vector(p); 33 | delete p; 34 | return 0; 35 | } -------------------------------------------------------------------------------- /ch12/exercise12_7.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::vector; 6 | 7 | std::shared_ptr> alloc_vector() 8 | { 9 | return std::make_shared>(); 10 | } 11 | 12 | void assign_vector(std::shared_ptr> p) 13 | { 14 | int i; 15 | while (std::cin >> i) 16 | { 17 | p->push_back(i); 18 | } 19 | } 20 | 21 | void print_vector(std::shared_ptr> p) 22 | { 23 | for (auto i : *p) 24 | { 25 | std::cout << i << std::endl; 26 | } 27 | } 28 | 29 | int main() 30 | { 31 | auto p = alloc_vector(); 32 | assign_vector(p); 33 | print_vector(p); 34 | return 0; 35 | } -------------------------------------------------------------------------------- /ch13/exercise13_11.h: -------------------------------------------------------------------------------- 1 | #ifndef ex13_11_h 2 | #define ex13_11_h 3 | 4 | #include 5 | 6 | class HasPtr 7 | { 8 | public: 9 | HasPtr(const std::string &s = std::string()) : ps(new std::string(s)), i(0) {} 10 | HasPtr(const HasPtr &hp) : ps(new std::string(*hp.ps)), i(hp.i) {} 11 | HasPtr& operator=(const HasPtr &hp) 12 | { 13 | std::string *new_ps = new std::string(*hp.ps); 14 | delete ps; 15 | ps = new_ps; 16 | i = hp.i; 17 | return *this; 18 | } 19 | ~HasPtr() 20 | { 21 | delete ps; 22 | } 23 | private: 24 | std::string *ps; 25 | int i; 26 | }; 27 | 28 | #endif // !ex13_11_h 29 | -------------------------------------------------------------------------------- /ch13/exercise13_13.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct X 6 | { 7 | X() { std::cout << "X()" << std::endl; } 8 | X(const X&) { std::cout << "X(const X&)" << std::endl; } 9 | X& operator=(const X&) { std::cout << "X& operator=(const X&)" << std::endl; return *this; } 10 | ~X() { std::cout << "~X()" << std::endl; } 11 | }; 12 | 13 | void f(const X &rx, X x) 14 | { 15 | std::vector vec; 16 | vec.reserve(2); 17 | vec.push_back(rx); 18 | vec.push_back(x); 19 | } 20 | 21 | int main() 22 | { 23 | X *px = new X; 24 | f(*px, *px); 25 | delete px; 26 | 27 | return 0; 28 | } -------------------------------------------------------------------------------- /ch13/exercise13_17_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class numbered 4 | { 5 | public: 6 | numbered() 7 | { 8 | mysn = unique++; 9 | } 10 | 11 | int mysn; 12 | static int unique; 13 | }; 14 | 15 | int numbered::unique = 10; 16 | 17 | void f(numbered s) 18 | { 19 | std::cout << s.mysn << std::endl; 20 | } 21 | 22 | int main() 23 | { 24 | numbered a, b = a, c = b; 25 | f(a); 26 | f(b); 27 | f(c); 28 | } -------------------------------------------------------------------------------- /ch13/exercise13_17_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class numbered { 4 | public: 5 | numbered() { 6 | mysn = unique++; 7 | } 8 | numbered(const numbered& n) 9 | { 10 | mysn = unique++; 11 | } 12 | 13 | int mysn; 14 | static int unique; 15 | }; 16 | 17 | int numbered::unique = 10; 18 | 19 | void f(numbered s) { 20 | std::cout << s.mysn << std::endl; 21 | } 22 | 23 | int main() 24 | { 25 | numbered a, b = a, c = b; 26 | f(a); 27 | f(b); 28 | f(c); 29 | } -------------------------------------------------------------------------------- /ch13/exercise13_17_3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class numbered 4 | { 5 | public: 6 | numbered() 7 | { 8 | mysn = unique++; 9 | } 10 | numbered(const numbered& n) 11 | { 12 | mysn = unique++; 13 | } 14 | 15 | int mysn; 16 | static int unique; 17 | }; 18 | 19 | int numbered::unique = 10; 20 | 21 | void f(const numbered& s) 22 | { 23 | std::cout << s.mysn << std::endl; 24 | } 25 | 26 | int main() 27 | { 28 | numbered a, b = a, c = b; 29 | f(a); 30 | f(b); 31 | f(c); 32 | } -------------------------------------------------------------------------------- /ch13/exercise13_18.h: -------------------------------------------------------------------------------- 1 | #ifndef ex13_18_h 2 | #define ex13_18_h 3 | 4 | #include 5 | using std::string; 6 | 7 | class Employee 8 | { 9 | public: 10 | Employee(); 11 | Employee(const string& name); 12 | 13 | const int id() const { return id_; } 14 | 15 | private: 16 | string name_; 17 | int id_; 18 | static int s_increment; 19 | }; 20 | 21 | int Employee::s_increment = 0; 22 | Employee::Employee() 23 | { 24 | id_ = s_increment++; 25 | } 26 | 27 | Employee::Employee(const string& name) 28 | { 29 | id_ = s_increment++; 30 | name_ = name; 31 | } 32 | 33 | #endif -------------------------------------------------------------------------------- /ch13/exercise13_19.h: -------------------------------------------------------------------------------- 1 | #ifndef ex13_19_h 2 | #define ex13_19_h 3 | 4 | #include 5 | using std::string; 6 | 7 | class Employee 8 | { 9 | public: 10 | Employee(); 11 | Employee(const string &name); 12 | Employee(const Employee&) = delete; 13 | Employee& operator=(const Employee&) = delete; 14 | 15 | const int id() const { return id_; } 16 | 17 | private: 18 | string name_; 19 | int id_; 20 | static int s_increment; 21 | }; 22 | 23 | #endif -------------------------------------------------------------------------------- /ch13/exercise13_22.h: -------------------------------------------------------------------------------- 1 | #ifndef ex13_22_h 2 | #define ex13_22_h 3 | 4 | #include 5 | class HasPtr 6 | { 7 | public: 8 | HasPtr(const std::string &s = std::string()) : ps(new std::string(s)), i(0) {} 9 | HasPtr(const HasPtr &hp) : ps(new std::string(*hp.ps)), i(hp.i) {} 10 | HasPtr& operator=(const HasPtr &hp) 11 | { 12 | auto new_p = new std::string(*hp.ps); 13 | delete ps; 14 | ps = new_p; 15 | i = hp.i; 16 | return *this; 17 | } 18 | ~HasPtr() 19 | { 20 | delete ps; 21 | } 22 | private: 23 | std::string *ps; 24 | int i; 25 | }; 26 | 27 | #endif // !ex13_22_h 28 | -------------------------------------------------------------------------------- /ch13/exercise13_27.h: -------------------------------------------------------------------------------- 1 | #ifndef ex13_27_h 2 | #define ex13_27_h 3 | 4 | #include 5 | 6 | class HasPtr 7 | { 8 | public: 9 | HasPtr(const std::string& s = std::string()) :ps(new std::string(s)), i(0), use(new size_t(1)) {} 10 | HasPtr(const HasPtr& hp) :ps(hp.ps), use(hp.use), i(hp.i) { ++*use; } 11 | HasPtr& operator=(const HasPtr& rhs) 12 | { 13 | ++*rhs.use; 14 | if (--*use == 0) 15 | { 16 | delete ps; 17 | delete use; 18 | } 19 | ps = rhs.ps; 20 | i = rhs.i; 21 | use = rhs.use; 22 | return *this; 23 | } 24 | ~HasPtr() 25 | { 26 | if (--*use == 0) 27 | { 28 | delete ps; 29 | delete use; 30 | } 31 | } 32 | private: 33 | std::string *ps; 34 | int i; 35 | size_t *use; 36 | }; 37 | 38 | #endif -------------------------------------------------------------------------------- /ch13/exercise13_28.h: -------------------------------------------------------------------------------- 1 | #ifndef ex13_28_h 2 | #define ex13_28_h 3 | 4 | #include 5 | using std::string; 6 | 7 | class TreeNode 8 | { 9 | public: 10 | TreeNode() : value(string()), count(new int(1)), left(nullptr), right(nullptr) {} 11 | TreeNode(const TreeNode &rhs) : value(rhs.value), count(rhs.count), left(rhs.left), right(rhs.right) { ++*count; } 12 | TreeNode& operator=(const TreeNode &rhs); 13 | ~TreeNode() 14 | { 15 | if (--*count == 0) 16 | { 17 | if (left) 18 | { 19 | delete left; 20 | left = nullptr; 21 | } 22 | if (right) 23 | { 24 | delete right; 25 | right = nullptr; 26 | } 27 | delete count; 28 | count = nullptr; 29 | } 30 | } 31 | 32 | private: 33 | std::string value; 34 | int *count; 35 | TreeNode *left; 36 | TreeNode *right; 37 | }; 38 | 39 | TreeNode& TreeNode::operator=(const TreeNode &rhs) 40 | { 41 | ++*rhs.count; 42 | if (--*count == 0) 43 | { 44 | if (left) 45 | { 46 | delete left; 47 | } 48 | if (right) 49 | { 50 | delete right; 51 | } 52 | 53 | delete count; 54 | } 55 | value = rhs.value; 56 | left = rhs.left; 57 | right = rhs.right; 58 | count = rhs.count; 59 | return *this; 60 | } 61 | 62 | 63 | class BinStrTree 64 | { 65 | public: 66 | BinStrTree() : root(new TreeNode()) {} 67 | BinStrTree(const BinStrTree &bst) : root(new TreeNode(*bst.root)) {} 68 | BinStrTree& operator=(const BinStrTree &bst); 69 | ~BinStrTree() { delete root; } 70 | 71 | private: 72 | TreeNode *root; 73 | }; 74 | 75 | BinStrTree& BinStrTree::operator=(const BinStrTree &bst) 76 | { 77 | TreeNode *new_root = new TreeNode(*bst.root); 78 | delete root; 79 | root = new_root; 80 | return *this; 81 | } 82 | 83 | 84 | #endif -------------------------------------------------------------------------------- /ch13/exercise13_30.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex13_11_h 2 | #define CP5_ex13_11_h 3 | 4 | #include 5 | #include 6 | 7 | class HasPtr 8 | { 9 | public: 10 | friend void swap(HasPtr&, HasPtr&); 11 | HasPtr(const std::string &s = std::string()) : ps(new std::string(s)), i(0) {} 12 | HasPtr(const HasPtr &hp) : ps(new std::string(*hp.ps)), i(hp.i) {} 13 | HasPtr& operator=(const HasPtr &hp) 14 | { 15 | auto new_p = new std::string(*hp.ps); 16 | delete ps; 17 | ps = new_p; 18 | i = hp.i; 19 | return *this; 20 | } 21 | ~HasPtr() 22 | { 23 | delete ps; 24 | } 25 | 26 | void show() { std::cout << *ps << std::endl; } 27 | private: 28 | std::string *ps; 29 | int i; 30 | }; 31 | 32 | inline 33 | void swap(HasPtr& lhs, HasPtr& rhs) 34 | { 35 | using std::swap; 36 | swap(lhs.ps, rhs.ps); 37 | swap(lhs.i, rhs.i); 38 | std::cout << "call swap(HasPtr& lhs, HasPtr& rhs)" << std::endl; 39 | } 40 | 41 | #endif -------------------------------------------------------------------------------- /ch13/exercise13_31.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex13_31_h 2 | #define CP5_ex13_31_h 3 | 4 | #include 5 | #include 6 | 7 | class HasPtr 8 | { 9 | public: 10 | friend void swap(HasPtr&, HasPtr&); 11 | friend bool operator<(const HasPtr &lhs, const HasPtr &rhs); 12 | 13 | HasPtr(const std::string &s = std::string()) 14 | : ps(new std::string(s)), i(0) 15 | {} 16 | 17 | HasPtr(const HasPtr &hp) 18 | : ps(new std::string(*hp.ps)), i(hp.i) 19 | {} 20 | 21 | HasPtr& operator=(HasPtr tmp) 22 | { 23 | this->swap(tmp); 24 | return *this; 25 | } 26 | 27 | ~HasPtr() 28 | { 29 | delete ps; 30 | } 31 | 32 | void swap(HasPtr &rhs) 33 | { 34 | using std::swap; 35 | swap(ps, rhs.ps); 36 | swap(i, rhs.i); 37 | std::cout << "call swap(HasPtr &rhs)" << std::endl; 38 | } 39 | 40 | void show() const 41 | { 42 | std::cout << *ps << std::endl; 43 | } 44 | private: 45 | std::string *ps; 46 | int i; 47 | }; 48 | 49 | void swap(HasPtr& lhs, HasPtr& rhs) 50 | { 51 | lhs.swap(rhs); 52 | } 53 | 54 | bool operator<(const HasPtr &lhs, const HasPtr &rhs) 55 | { 56 | return *lhs.ps < *rhs.ps; 57 | } 58 | 59 | #endif -------------------------------------------------------------------------------- /ch13/exercise13_34.h: -------------------------------------------------------------------------------- 1 | #ifndef ex13_34_h 2 | #define ex13_34_h 3 | 4 | #include 5 | #include 6 | 7 | class Folder; 8 | 9 | class Message 10 | { 11 | friend void swap(Message &, Message &); 12 | friend void swap(Folder &, Folder &); 13 | friend class Folder; 14 | public: 15 | explicit Message(const std::string& s = "") :contents(s) {} 16 | Message(const Message&); 17 | Message& operator=(const Message&); 18 | ~Message(); 19 | void save(Folder&); 20 | void remove(Folder&); 21 | void print_debug(); 22 | 23 | private: 24 | std::string contents; 25 | std::set folders; 26 | 27 | void add_to_Folders(const Message&); 28 | void remove_from_Folders(); 29 | 30 | void addFldr(Folder* f) { folders.insert(f); } 31 | void remFlddr(Folder* f) { folders.erase(f); } 32 | }; 33 | 34 | void swap(Message&, Message&); 35 | 36 | class Folder 37 | { 38 | friend void swap(Message&, Message&); 39 | friend void swap(Folder&, Folder&); 40 | friend class Message; 41 | public: 42 | Folder() = default; 43 | Folder(const Folder&); 44 | Folder& operator=(const Folder&); 45 | ~Folder(); 46 | void print_debug(); 47 | 48 | private: 49 | std::set msgs; 50 | 51 | void add_to_Message(const Folder&); 52 | void remove_to_Message(); 53 | 54 | void addMsg(Message* m) { msgs.insert(m); } 55 | void remMsg(Message *m) { msgs.erase(m); } 56 | }; 57 | 58 | void swap(Folder&, Folder&); 59 | 60 | 61 | #endif // !ex13_34_h 62 | -------------------------------------------------------------------------------- /ch13/exercise13_39.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise13_39.h" 2 | 3 | void StrVec::push_back(const std::string& s) 4 | { 5 | chk_n_alloc(); 6 | alloc.construct(first_free++, s); 7 | } 8 | 9 | std::pair 10 | StrVec::alloc_n_copy(const std::string* b, const std::string* e) 11 | { 12 | auto data = alloc.allocate(e - b); 13 | return{ data, std::uninitialized_copy(b, e, data) }; 14 | } 15 | 16 | void StrVec::free() 17 | { 18 | if (elements) 19 | { 20 | for (auto p = first_free; p != elements;) 21 | alloc.destroy(--p); 22 | alloc.deallocate(elements, cap - elements); 23 | } 24 | } 25 | 26 | StrVec::StrVec(const StrVec& rhs) 27 | { 28 | auto newdata = alloc_n_copy(rhs.begin(), rhs.end()); 29 | elements = newdata.first; 30 | first_free = cap = newdata.second; 31 | } 32 | //ex13.40 33 | StrVec::StrVec(std::initializer_list il) 34 | { 35 | range_initialize(il.begin(), il.end()); 36 | } 37 | 38 | StrVec::~StrVec() 39 | { 40 | free(); 41 | } 42 | 43 | StrVec& StrVec::operator=(const StrVec& rhs) 44 | { 45 | auto data = alloc_n_copy(rhs.begin(), rhs.end()); 46 | free(); 47 | elements = data.first; 48 | first_free = cap = data.second; 49 | return *this; 50 | } 51 | 52 | void StrVec::alloc_n_move(size_t new_cap) 53 | { 54 | auto newdata = alloc.allocate(new_cap); 55 | auto dest = newdata; 56 | auto elem = elements; 57 | for (size_t i = 0; i != size(); ++i) 58 | alloc.construct(dest++, std::move(*elem++)); 59 | free(); 60 | elements = newdata; 61 | first_free = dest; 62 | cap = elements + new_cap; 63 | } 64 | 65 | void StrVec::reallocate() 66 | { 67 | auto newcapacity = size() ? 2 * size() : 1; 68 | alloc_n_move(newcapacity); 69 | } 70 | 71 | //ex13.40 72 | void StrVec::range_initialize(const std::string* first, const std::string* last) 73 | { 74 | auto newdata = alloc_n_copy(first, last); 75 | elements = newdata.first; 76 | first_free = cap = newdata.second; 77 | } -------------------------------------------------------------------------------- /ch13/exercise13_39.h: -------------------------------------------------------------------------------- 1 | #ifndef ex13_39_h 2 | #define ex13_39_h 3 | 4 | #include 5 | #include 6 | 7 | class StrVec 8 | { 9 | public: 10 | StrVec() :elements(nullptr), first_free(nullptr), cap(nullptr) {} 11 | StrVec(const StrVec&); 12 | StrVec(std::initializer_list);//ex13.40 13 | StrVec& operator=(const StrVec&); 14 | ~StrVec(); 15 | 16 | void push_back(const std::string&); 17 | size_t size() const { return first_free - elements; } 18 | size_t capacity() const { return cap - elements; } 19 | std::string *begin() const { return elements; } 20 | std::string *end() const { return first_free; } 21 | 22 | private: 23 | std::pair alloc_n_copy(const std::string*, const std::string*); 24 | void free(); 25 | void chk_n_alloc() { if (size() == capacity()) reallocate(); } 26 | void reallocate(); 27 | void alloc_n_move(size_t new_cap); 28 | void range_initialize(const std::string*, const std::string*);//ex13.40 29 | 30 | private: 31 | std::string *elements; 32 | std::string *first_free; 33 | std::string *cap; 34 | std::allocator alloc; 35 | }; 36 | 37 | 38 | #endif -------------------------------------------------------------------------------- /ch13/exercise13_44.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise13_44.h" 2 | 3 | #include 4 | #include 5 | 6 | std::pair 7 | String::alloc_n_copy(const char* b, const char* e) 8 | { 9 | auto str = alloc.allocate(e - b); 10 | return{ str, std::uninitialized_copy(b, e, str) }; 11 | } 12 | 13 | void String::range_initializer(const char* first, const char* last) 14 | { 15 | auto newstr = alloc_n_copy(first, last); 16 | elements = newstr.first; 17 | end = newstr.second; 18 | } 19 | 20 | String::String(const char* s) 21 | { 22 | char *s1 = const_cast(s); 23 | while (*s1) 24 | { 25 | ++s1; 26 | } 27 | range_initializer(s, ++s1); 28 | } 29 | 30 | String::String(const String& rhs) 31 | { 32 | range_initializer(rhs.elements, rhs.end); 33 | std::cout << "copy constructor" << std::endl; 34 | } 35 | 36 | void String::free() 37 | { 38 | if (elements) 39 | { 40 | std::for_each(elements, end, [this](char &c) { alloc.destroy(&c); }); 41 | alloc.deallocate(elements, end - elements); 42 | } 43 | } 44 | 45 | String::~String() 46 | { 47 | free(); 48 | } 49 | 50 | String& String::operator=(const String& rhs) 51 | { 52 | auto newstr = alloc_n_copy(rhs.elements, rhs.end); 53 | free(); 54 | elements = newstr.first; 55 | end = newstr.second; 56 | std::cout << "copy-assignment" << std::endl; 57 | return *this; 58 | } -------------------------------------------------------------------------------- /ch13/exercise13_44.h: -------------------------------------------------------------------------------- 1 | #ifndef String_h 2 | #define String_h 3 | 4 | #include 5 | 6 | class String 7 | { 8 | public: 9 | String() :String("") {} 10 | String(const char *); 11 | String(const String&); 12 | String& operator=(const String&); 13 | ~String(); 14 | 15 | const char* c_str() const { return elements; } 16 | size_t size() const { return end - elements; } 17 | size_t length() const { return end - elements + 1; } 18 | 19 | private: 20 | std::pair alloc_n_copy(const char*, const char*); 21 | void range_initializer(const char*, const char*); 22 | void free(); 23 | 24 | private: 25 | char *elements; 26 | char *end; 27 | std::allocator alloc; 28 | }; 29 | 30 | #endif -------------------------------------------------------------------------------- /ch13/exercise13_44_main.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise13_44.h" 2 | #include 3 | #include 4 | 5 | // Test reference to http://coolshell.cn/articles/10478.html 6 | 7 | void foo(String x) 8 | { 9 | std::cout << x.c_str() << std::endl; 10 | } 11 | 12 | void bar(const String& x) 13 | { 14 | std::cout << x.c_str() << std::endl; 15 | } 16 | 17 | String baz() 18 | { 19 | String ret("world"); 20 | return ret; 21 | } 22 | 23 | int main() 24 | { 25 | char text[] = "world"; 26 | 27 | String s0; 28 | String s1("hello"); 29 | String s2(s0); 30 | String s3 = s1; 31 | String s4(text); 32 | s2 = s1; 33 | 34 | foo(s1); 35 | bar(s1); 36 | foo("temporary"); 37 | bar("temporary"); 38 | String s5 = baz(); 39 | 40 | std::vector svec; 41 | svec.reserve(8); 42 | svec.push_back(s0); 43 | svec.push_back(s1); 44 | svec.push_back(s2); 45 | svec.push_back(s3); 46 | svec.push_back(s4); 47 | svec.push_back(s5); 48 | svec.push_back(baz()); 49 | svec.push_back("good job"); 50 | 51 | for (const auto &s : svec) 52 | { 53 | std::cout << s.c_str() << std::endl; 54 | } 55 | } -------------------------------------------------------------------------------- /ch13/exercise13_5.h: -------------------------------------------------------------------------------- 1 | #ifndef ex13_5_h 2 | #define ex13_5_h 3 | 4 | #include 5 | 6 | class HasPtr 7 | { 8 | public: 9 | HasPtr(const std::string &s = std::string()) : ps(new std::string(s)), i(0) {} 10 | HasPtr(const HasPtr& hp) :ps(new std::string(*hp.ps)), i(hp.i) {} 11 | private: 12 | std::string *ps; 13 | int i; 14 | }; 15 | 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /ch13/exercise13_53.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise13_53.h" 2 | #include 3 | 4 | inline void swap(HasPtr &lhs, HasPtr &rhs) 5 | { 6 | using std::swap; 7 | swap(lhs.ps, rhs.ps); 8 | swap(lhs.i, rhs.i); 9 | std::cout << "call swap" << std::endl; 10 | } 11 | 12 | HasPtr::HasPtr(const std::string &s) : ps(new std::string(s)), i(0) 13 | { 14 | std::cout << "call constructor" << std::endl; 15 | } 16 | 17 | HasPtr::HasPtr(const HasPtr &hp) : ps(new std::string(*hp.ps)), i(hp.i) 18 | { 19 | std::cout << "call copy constructor" << std::endl; 20 | } 21 | 22 | HasPtr::HasPtr(HasPtr &&p) noexcept : ps(p.ps), i(p.i) 23 | { 24 | p.ps = 0; 25 | std::cout << "call move constructor" << std::endl; 26 | } 27 | 28 | HasPtr& HasPtr::operator=(HasPtr rhs) 29 | { 30 | swap(*this, rhs); 31 | return *this; 32 | } 33 | 34 | HasPtr::~HasPtr() 35 | { 36 | std::cout << "call destructor" << std::endl; 37 | delete ps; 38 | } -------------------------------------------------------------------------------- /ch13/exercise13_53.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex13_53_h 2 | #define CP5_ex13_53_h 3 | 4 | #include 5 | 6 | class HasPtr 7 | { 8 | public: 9 | friend void swap(HasPtr&, HasPtr&); 10 | HasPtr(const std::string &s = std::string()); 11 | HasPtr(const HasPtr &hp); 12 | HasPtr(HasPtr &&p) noexcept; 13 | HasPtr& operator=(HasPtr rhs); 14 | //HasPtr& operator=(const HasPtr &rhs); 15 | //HasPtr& operator=(HasPtr &&rhs) noexcept; 16 | ~HasPtr(); 17 | 18 | private: 19 | std::string *ps; 20 | int i; 21 | }; 22 | 23 | #endif // CP5_ex13_53_h -------------------------------------------------------------------------------- /ch13/exercise13_58.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::vector; using std::sort; 6 | 7 | class Foo 8 | { 9 | public: 10 | Foo sorted() && ; 11 | Foo sorted() const &; 12 | private: 13 | vector data; 14 | }; 15 | 16 | Foo Foo::sorted() && { 17 | sort(data.begin(), data.end()); 18 | std::cout << "&&" << std::endl; // debug 19 | return *this; 20 | } 21 | 22 | Foo Foo::sorted() const & 23 | { 24 | // Foo ret(*this); 25 | // sort(ret.data.begin(), ret.data.end()); 26 | // return ret; 27 | 28 | std::cout << "const &" << std::endl; // debug 29 | 30 | // Foo ret(*this); 31 | // ret.sorted(); // Exercise 13.56 32 | // return ret; 33 | 34 | return Foo(*this).sorted(); // Exercise 13.57 35 | } 36 | 37 | int main() 38 | { 39 | Foo().sorted(); // call "&&" 40 | Foo f; 41 | f.sorted(); // call "const &" 42 | } -------------------------------------------------------------------------------- /ch13/exercise13_8.h: -------------------------------------------------------------------------------- 1 | #ifndef ex13_8_h 2 | #define ex13_8_h 3 | 4 | #include 5 | 6 | class HasPtr 7 | { 8 | public: 9 | HasPtr(const std::string& s = std::string()) :ps(new std::string()), i(0) {} 10 | HasPtr(const HasPtr& hp) :ps(new std::string(*hp.ps)), i(hp.i) {} 11 | HasPtr& operator=(const HasPtr& hp) 12 | { 13 | std::string *new_ps = new std::string(*hp.ps); 14 | delete ps; 15 | ps = new_ps; 16 | i = hp.i; 17 | return *this; 18 | } 19 | private: 20 | std::string *ps; 21 | int i; 22 | }; 23 | 24 | #endif // !ex13_8_h 25 | -------------------------------------------------------------------------------- /ch14/exercise14_15.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise14_15.h" 2 | 3 | std::istream& operator>>(std::istream &in, Book &book) 4 | { 5 | in >> book.no_ >> book.name_ >> book.author_ >> book.pubdate_ >> book.number_; 6 | return in; 7 | } 8 | 9 | std::ostream& operator<<(std::ostream &out, const Book &book) 10 | { 11 | out << book.no_ << " " << book.name_ << " " << book.author_ << " " << book.pubdate_ << " " << book.number_ << std::endl; 12 | return out; 13 | } 14 | 15 | bool operator==(const Book &lhs, const Book &rhs) 16 | { 17 | return lhs.no_ == rhs.no_; 18 | } 19 | 20 | bool operator!=(const Book &lhs, const Book &rhs) 21 | { 22 | return !(lhs == rhs); 23 | } 24 | 25 | bool operator<(const Book &lhs, const Book &rhs) 26 | { 27 | return lhs.no_ < rhs.no_; 28 | } 29 | 30 | bool operator>(const Book &lhs, const Book &rhs) 31 | { 32 | return rhs < lhs; 33 | } 34 | 35 | Book& Book::operator+=(const Book &rhs) 36 | { 37 | if (rhs == *this) 38 | this->number_ += rhs.number_; 39 | 40 | return *this; 41 | } 42 | 43 | Book operator+(const Book &lhs, const Book &rhs) 44 | { 45 | Book book = lhs; 46 | book += rhs; 47 | return book; 48 | } -------------------------------------------------------------------------------- /ch14/exercise14_15.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_CH14_EX14_15_H_ 2 | #define CP5_CH14_EX14_15_H_ 3 | 4 | #include 5 | #include 6 | 7 | class Book 8 | { 9 | friend std::istream& operator>>(std::istream&, Book&); 10 | friend std::ostream& operator<<(std::ostream&, const Book&); 11 | friend bool operator==(const Book&, const Book&); 12 | friend bool operator!=(const Book&, const Book&); 13 | friend bool operator<(const Book&, const Book&); 14 | friend bool operator>(const Book&, const Book&); 15 | friend Book operator+(const Book&, const Book&); 16 | 17 | public: 18 | Book() = default; 19 | Book(unsigned no, std::string name, std::string author, std::string pubdate, unsigned number) :no_(no), name_(name), author_(author), pubdate_(pubdate), number_(number) {} 20 | Book(std::istream &in) { in >> *this; } 21 | 22 | Book& operator+=(const Book&); 23 | 24 | private: 25 | unsigned no_; 26 | std::string name_; 27 | std::string author_; 28 | std::string pubdate_; 29 | unsigned number_; 30 | }; 31 | 32 | std::istream& operator>>(std::istream&, Book&); 33 | std::ostream& operator<<(std::ostream&, const Book&); 34 | bool operator==(const Book&, const Book&); 35 | bool operator!=(const Book&, const Book&); 36 | bool operator<(const Book&, const Book&); 37 | bool operator>(const Book&, const Book&); 38 | Book operator+(const Book&, const Book&); 39 | 40 | #endif // CP5_CH14_EX14_15_H_ -------------------------------------------------------------------------------- /ch14/exercise14_15_main.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise14_15.h" 2 | 3 | int main() 4 | { 5 | Book cp5_1(12345, "CP5", "Lippmen", "2012", 2); 6 | Book cp5_2(12345, "CP5", "Lippmen", "2012", 4); 7 | 8 | std::cout << cp5_1 + cp5_2 << std::endl; 9 | } -------------------------------------------------------------------------------- /ch14/exercise14_2.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise14_2.h" 2 | 3 | Sales_data::Sales_data(std::istream &is) : Sales_data() 4 | { 5 | is >> *this; 6 | } 7 | 8 | Sales_data& Sales_data::operator+=(const Sales_data &rhs) 9 | { 10 | units_sold += rhs.units_sold; 11 | revenue += rhs.revenue; 12 | return *this; 13 | } 14 | 15 | std::istream& operator>>(std::istream &is, Sales_data &item) 16 | { 17 | double price = 0.0; 18 | is >> item.bookNo >> item.units_sold >> price; 19 | if (is) 20 | item.revenue = price * item.units_sold; 21 | else 22 | item = Sales_data(); 23 | return is; 24 | } 25 | 26 | std::ostream& operator<<(std::ostream &os, const Sales_data &item) 27 | { 28 | os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price(); 29 | return os; 30 | } 31 | 32 | Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs) 33 | { 34 | Sales_data sum = lhs; 35 | sum += rhs; 36 | return sum; 37 | } -------------------------------------------------------------------------------- /ch14/exercise14_2.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_CH14_EX14_02_H 2 | #define CP5_CH14_EX14_02_H 3 | 4 | #include 5 | #include 6 | 7 | class Sales_data 8 | { 9 | friend std::istream& operator>>(std::istream&, Sales_data&); // input 10 | friend std::ostream& operator<<(std::ostream&, const Sales_data&); // output 11 | friend Sales_data operator+(const Sales_data&, const Sales_data&); // addition 12 | 13 | public: 14 | Sales_data(const std::string &s, unsigned n, double p) :bookNo(s), units_sold(n), revenue(n*p) {} 15 | Sales_data() : Sales_data("", 0, 0.0f) {} 16 | Sales_data(const std::string &s) : Sales_data(s, 0, 0.0f) {} 17 | Sales_data(std::istream &is); 18 | 19 | Sales_data& operator+=(const Sales_data&); // compound-assignment 20 | std::string isbn() const { return bookNo; } 21 | 22 | private: 23 | inline double avg_price() const; 24 | 25 | std::string bookNo; 26 | unsigned units_sold = 0; 27 | double revenue = 0.0; 28 | }; 29 | 30 | std::istream& operator>>(std::istream&, Sales_data&); 31 | std::ostream& operator<<(std::ostream&, const Sales_data&); 32 | Sales_data operator+(const Sales_data&, const Sales_data&); 33 | 34 | inline double Sales_data::avg_price() const 35 | { 36 | return units_sold ? revenue / units_sold : 0; 37 | } 38 | 39 | #endif // CP5_CH14_EX14_02_H -------------------------------------------------------------------------------- /ch14/exercise14_22.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise14_22.h" 2 | 3 | Sales_data::Sales_data(std::istream &is) : Sales_data() 4 | { 5 | is >> *this; 6 | } 7 | 8 | Sales_data& Sales_data::operator+=(const Sales_data &rhs) 9 | { 10 | units_sold += rhs.units_sold; 11 | revenue += rhs.revenue; 12 | return *this; 13 | } 14 | 15 | std::istream& operator>>(std::istream &is, Sales_data &item) 16 | { 17 | double price = 0.0; 18 | is >> item.bookNo >> item.units_sold >> price; 19 | if (is) 20 | item.revenue = price * item.units_sold; 21 | else 22 | item = Sales_data(); 23 | return is; 24 | } 25 | 26 | std::ostream& operator<<(std::ostream &os, const Sales_data &item) 27 | { 28 | os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price(); 29 | return os; 30 | } 31 | 32 | Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs) 33 | { 34 | Sales_data sum = lhs; 35 | sum += rhs; 36 | return sum; 37 | } 38 | 39 | Sales_data& Sales_data::operator=(const std::string &isbn) 40 | { 41 | *this = Sales_data(isbn); 42 | return *this; 43 | } -------------------------------------------------------------------------------- /ch14/exercise14_22.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex14_22_h 2 | #define CP5_ex14_22_h 3 | 4 | #include 5 | #include 6 | 7 | class Sales_data 8 | { 9 | friend std::istream& operator>>(std::istream&, Sales_data&); 10 | friend std::ostream& operator<<(std::ostream&, const Sales_data&); 11 | friend Sales_data operator+(const Sales_data&, const Sales_data&); 12 | 13 | public: 14 | Sales_data(const std::string &s, unsigned n, double p) :bookNo(s), units_sold(n), revenue(n*p) {} 15 | Sales_data() : Sales_data("", 0, 0.0f) {} 16 | Sales_data(const std::string &s) : Sales_data(s, 0, 0.0f) {} 17 | Sales_data(std::istream &is); 18 | 19 | Sales_data& operator=(const std::string&); 20 | 21 | Sales_data& operator+=(const Sales_data&); 22 | std::string isbn() const { return bookNo; } 23 | 24 | private: 25 | inline double avg_price() const; 26 | 27 | std::string bookNo; 28 | unsigned units_sold = 0; 29 | double revenue = 0.0; 30 | }; 31 | 32 | std::istream& operator>>(std::istream&, Sales_data&); 33 | std::ostream& operator<<(std::ostream&, const Sales_data&); 34 | Sales_data operator+(const Sales_data&, const Sales_data&); 35 | 36 | inline double Sales_data::avg_price() const 37 | { 38 | return units_sold ? revenue / units_sold : 0; 39 | } 40 | 41 | #endif -------------------------------------------------------------------------------- /ch14/exercise14_22_main.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise14_22.h" 2 | 3 | int main() 4 | { 5 | std::string strCp5("C++ Primer 5th"); 6 | Sales_data cp5 = strCp5; 7 | std::cout << cp5 << std::endl; 8 | } -------------------------------------------------------------------------------- /ch14/exercise14_23.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_STRVEC_H_ 2 | #define CP5_STRVEC_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #ifndef _MSC_VER 9 | #define NOEXCEPT noexcept 10 | #else 11 | #define NOEXCEPT 12 | #endif 13 | 14 | class StrVec 15 | { 16 | friend bool operator==(const StrVec&, const StrVec&); 17 | friend bool operator!=(const StrVec&, const StrVec&); 18 | friend bool operator< (const StrVec&, const StrVec&); 19 | friend bool operator> (const StrVec&, const StrVec&); 20 | friend bool operator<=(const StrVec&, const StrVec&); 21 | friend bool operator>=(const StrVec&, const StrVec&); 22 | 23 | public: 24 | StrVec() : elements(nullptr), first_free(nullptr), cap(nullptr) {} 25 | StrVec(std::initializer_list); 26 | StrVec(const StrVec&); 27 | StrVec& operator=(const StrVec&); 28 | StrVec(StrVec&&) NOEXCEPT; 29 | StrVec& operator=(StrVec&&)NOEXCEPT; 30 | ~StrVec(); 31 | 32 | StrVec& operator=(std::initializer_list); 33 | 34 | void push_back(const std::string&); 35 | size_t size() const { return first_free - elements; } 36 | size_t capacity() const { return cap - elements; } 37 | std::string *begin() const { return elements; } 38 | std::string *end() const { return first_free; } 39 | 40 | std::string& at(size_t pos) { return *(elements + pos); } 41 | const std::string& at(size_t pos) const { return *(elements + pos); } 42 | 43 | void reserve(size_t new_cap); 44 | void resize(size_t count); 45 | void resize(size_t count, const std::string&); 46 | 47 | private: 48 | std::pair alloc_n_copy(const std::string*, const std::string*); 49 | void free(); 50 | void chk_n_alloc() { if (size() == capacity()) reallocate(); } 51 | void reallocate(); 52 | void alloc_n_move(size_t new_cap); 53 | void range_initialize(const std::string*, const std::string*); 54 | 55 | private: 56 | std::string *elements; 57 | std::string *first_free; 58 | std::string *cap; 59 | std::allocator alloc; 60 | }; 61 | 62 | bool operator==(const StrVec&, const StrVec&); 63 | bool operator!=(const StrVec&, const StrVec&); 64 | bool operator< (const StrVec&, const StrVec&); 65 | bool operator> (const StrVec&, const StrVec&); 66 | bool operator<=(const StrVec&, const StrVec&); 67 | bool operator>=(const StrVec&, const StrVec&); 68 | 69 | #endif -------------------------------------------------------------------------------- /ch14/exercise14_23_main.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise14_23.h" 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | StrVec vec; 8 | vec.reserve(6); 9 | std::cout << "capacity(reserve to 6): " << vec.capacity() << std::endl; 10 | 11 | vec.reserve(4); 12 | std::cout << "capacity(reserve to 4): " << vec.capacity() << std::endl; 13 | 14 | vec.push_back("hello"); 15 | vec.push_back("world"); 16 | 17 | vec.resize(4); 18 | 19 | for (auto i = vec.begin(); i != vec.end(); ++i) 20 | std::cout << *i << std::endl; 21 | std::cout << "-EOF-" << std::endl; 22 | 23 | vec.resize(1); 24 | 25 | for (auto i = vec.begin(); i != vec.end(); ++i) 26 | std::cout << *i << std::endl; 27 | std::cout << "-EOF-" << std::endl; 28 | 29 | StrVec vec_list{ "hello", "world", "pezy" }; 30 | 31 | for (auto i = vec_list.begin(); i != vec_list.end(); ++i) 32 | std::cout << *i << " "; 33 | std::cout << std::endl; 34 | 35 | // Test operator== 36 | 37 | const StrVec const_vec_list = { "hello", "world", "pezy" }; 38 | if (vec_list == const_vec_list) 39 | for (const auto &str : const_vec_list) 40 | std::cout << str << " "; 41 | std::cout << std::endl; 42 | 43 | // Test operator< 44 | const StrVec const_vec_list_small = { "hello", "pezy", "ok" }; 45 | std::cout << (const_vec_list_small < const_vec_list) << std::endl; 46 | } -------------------------------------------------------------------------------- /ch14/exercise14_24_main.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise14_24.h" 2 | #include 3 | 4 | int main() 5 | { 6 | 7 | Date lhs(9999999), rhs(1); 8 | 9 | std::cout << (lhs -= 12000) << "\n"; 10 | 11 | 12 | return 0; 13 | } -------------------------------------------------------------------------------- /ch14/exercise14_35.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class GetInput 5 | { 6 | public: 7 | GetInput(std::istream &i = std::cin) : is(i) {} 8 | std::string operator()() const 9 | { 10 | std::string str; 11 | std::getline(is, str); 12 | return is ? str : std::string(); 13 | } 14 | 15 | private: 16 | std::istream &is; 17 | }; 18 | 19 | int main() 20 | { 21 | GetInput getInput; 22 | std::cout << getInput() << std::endl; 23 | } -------------------------------------------------------------------------------- /ch14/exercise14_36.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class GetInput 6 | { 7 | public: 8 | GetInput(std::istream &i = std::cin) : is(i) {} 9 | std::string operator()() const 10 | { 11 | std::string str; 12 | std::getline(is, str); 13 | return is ? str : std::string(); 14 | } 15 | 16 | private: 17 | std::istream &is; 18 | }; 19 | 20 | int main() 21 | { 22 | GetInput getInput; 23 | std::vector vec; 24 | for (std::string tmp; !(tmp = getInput()).empty();) vec.push_back(tmp); 25 | for (const auto &str : vec) std::cout << str << " "; 26 | std::cout << std::endl; 27 | } -------------------------------------------------------------------------------- /ch14/exercise14_37.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class IsEqual 6 | { 7 | int value; 8 | public: 9 | IsEqual(int v) : value(v) {} 10 | bool operator()(int elem) 11 | { 12 | return elem == value; 13 | } 14 | }; 15 | 16 | int main() 17 | { 18 | std::vector vec = { 3, 2, 1, 4, 3, 7, 8, 6 }; 19 | std::replace_if(vec.begin(), vec.end(), IsEqual(3), 5); 20 | for (int i : vec) std::cout << i << " "; 21 | std::cout << std::endl; 22 | } -------------------------------------------------------------------------------- /ch14/exercise14_38.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct IsInRange 8 | { 9 | IsInRange(std::size_t lower, std::size_t upper) 10 | :_lower(lower), _upper(upper) 11 | {} 12 | 13 | bool operator()(std::string const& str) const 14 | { 15 | return str.size() >= _lower && str.size() <= _upper; 16 | } 17 | 18 | std::size_t lower_limit() const 19 | { 20 | return _lower; 21 | } 22 | 23 | std::size_t upper_limit() const 24 | { 25 | return _upper; 26 | } 27 | private: 28 | std::size_t _lower; 29 | std::size_t _upper; 30 | }; 31 | 32 | int main() 33 | { 34 | //create predicates with various upper limits. 35 | std::size_t lower = 1; 36 | auto uppers = { 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 14u }; 37 | std::vector predicates; 38 | for (auto upper : uppers) 39 | predicates.push_back(IsInRange{ lower, upper }); 40 | 41 | //create count_table to store counts 42 | std::map count_table; 43 | for (auto upper : uppers) 44 | count_table[upper] = 0; 45 | 46 | //read file and count 47 | std::ifstream fin("../data/storyDataFile.txt"); 48 | for (std::string word; fin >> word; /* */) 49 | for (auto is_size_in_range : predicates) 50 | if (is_size_in_range(word)) 51 | ++count_table[is_size_in_range.upper_limit()]; 52 | 53 | //print 54 | for (auto pair : count_table) 55 | std::cout << "count in range [1, " << pair.first << "] : " << pair.second << std::endl; 56 | 57 | return 0; 58 | } -------------------------------------------------------------------------------- /ch14/exercise14_40.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | class ShorterString 9 | { 10 | public: 11 | bool operator()(string const& s1, string const& s2) const { return s1.size() < s2.size(); } 12 | }; 13 | 14 | class BiggerEqual 15 | { 16 | size_t sz_; 17 | public: 18 | BiggerEqual(size_t sz) : sz_(sz) {} 19 | bool operator()(string const& s) { return s.size() >= sz_; } 20 | }; 21 | 22 | class Print 23 | { 24 | public: 25 | void operator()(string const& s) { cout << s << " "; } 26 | }; 27 | 28 | string make_plural(size_t ctr, string const& word, string const& ending) 29 | { 30 | return (ctr > 1) ? word + ending : word; 31 | } 32 | 33 | void elimDups(vector &words) 34 | { 35 | sort(words.begin(), words.end()); 36 | auto end_unique = unique(words.begin(), words.end()); 37 | words.erase(end_unique, words.end()); 38 | } 39 | 40 | void biggies(vector &words, vector::size_type sz) 41 | { 42 | elimDups(words); 43 | stable_sort(words.begin(), words.end(), ShorterString()); 44 | auto wc = find_if(words.begin(), words.end(), BiggerEqual(sz)); 45 | auto count = words.end() - wc; 46 | cout << count << " " << make_plural(count, "word", "s") << " of length " << sz << " or longer" << endl; 47 | for_each(wc, words.end(), Print()); 48 | cout << endl; 49 | } 50 | 51 | int main() 52 | { 53 | vector vec{ "fox", "jumps", "over", "quick", "red", "red", "slow", "the", "turtle" }; 54 | biggies(vec, 4); 55 | } -------------------------------------------------------------------------------- /ch14/exercise14_43.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | auto data = { 2, 3, 4, 5 }; 9 | int input; 10 | std::cin >> input; 11 | std::modulus mod; 12 | auto predicator = [&](int i) { return 0 == mod(input, i); }; 13 | auto is_divisible = std::any_of(data.begin(), data.end(), predicator); 14 | std::cout << (is_divisible ? "Yes!" : "No!") << std::endl; 15 | 16 | return 0; 17 | } -------------------------------------------------------------------------------- /ch14/exercise14_44.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int add(int i, int j) { return i + j; } 7 | auto mod = [](int i, int j) { return i % j; }; 8 | struct Div { int operator ()(int i, int j) const { return i / j; } }; 9 | 10 | auto binops = std::map> 11 | { 12 | { "+", add }, // function pointer 13 | { "-", std::minus() }, // library functor 14 | { "/", Div() }, // user-defined functor 15 | { "*", [](int i, int j) { return i*j; } }, // unnamed lambda 16 | { "%", mod } // named lambda object 17 | }; 18 | 19 | 20 | int main() 21 | { 22 | while (std::cout << "Pls enter as: num operator num :\n", true) 23 | { 24 | int lhs, rhs; std::string op; 25 | std::cin >> lhs >> op >> rhs; 26 | std::cout << binops[op](lhs, rhs) << std::endl; 27 | } 28 | 29 | return 0; 30 | } -------------------------------------------------------------------------------- /ch14/exercise14_45.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise14_45.h" 2 | 3 | Sales_data::Sales_data(std::istream &is) : Sales_data() 4 | { 5 | is >> *this; 6 | } 7 | 8 | Sales_data& Sales_data::operator+=(const Sales_data &rhs) 9 | { 10 | units_sold += rhs.units_sold; 11 | revenue += rhs.revenue; 12 | return *this; 13 | } 14 | 15 | std::istream& operator>>(std::istream &is, Sales_data &item) 16 | { 17 | double price = 0.0; 18 | is >> item.bookNo >> item.units_sold >> price; 19 | if (is) 20 | item.revenue = price * item.units_sold; 21 | else 22 | item = Sales_data(); 23 | return is; 24 | } 25 | 26 | std::ostream& operator<<(std::ostream &os, const Sales_data &item) 27 | { 28 | os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price(); 29 | return os; 30 | } 31 | 32 | Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs) 33 | { 34 | Sales_data sum = lhs; 35 | sum += rhs; 36 | return sum; 37 | } 38 | 39 | Sales_data& Sales_data::operator=(const std::string &isbn) 40 | { 41 | *this = Sales_data(isbn); 42 | return *this; 43 | } -------------------------------------------------------------------------------- /ch14/exercise14_45.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex14_45_h 2 | #define CP5_ex14_45_h 3 | 4 | #include 5 | #include 6 | 7 | class Sales_data 8 | { 9 | friend std::istream& operator>>(std::istream&, Sales_data&); 10 | friend std::ostream& operator<<(std::ostream&, const Sales_data&); 11 | friend Sales_data operator+(const Sales_data&, const Sales_data&); 12 | 13 | public: 14 | Sales_data(const std::string &s, unsigned n, double p) :bookNo(s), units_sold(n), revenue(n*p) {} 15 | Sales_data() : Sales_data("", 0, 0.0f) {} 16 | Sales_data(const std::string &s) : Sales_data(s, 0, 0.0f) {} 17 | Sales_data(std::istream &is); 18 | 19 | Sales_data& operator=(const std::string&); 20 | Sales_data& operator+=(const Sales_data&); 21 | explicit operator std::string() const { return bookNo; } 22 | explicit operator double() const { return avg_price(); } 23 | 24 | std::string isbn() const { return bookNo; } 25 | 26 | private: 27 | inline double avg_price() const; 28 | 29 | std::string bookNo; 30 | unsigned units_sold = 0; 31 | double revenue = 0.0; 32 | }; 33 | 34 | std::istream& operator>>(std::istream&, Sales_data&); 35 | std::ostream& operator<<(std::ostream&, const Sales_data&); 36 | Sales_data operator+(const Sales_data&, const Sales_data&); 37 | 38 | inline double Sales_data::avg_price() const 39 | { 40 | return units_sold ? revenue / units_sold : 0; 41 | } 42 | 43 | #endif -------------------------------------------------------------------------------- /ch14/exercise14_45_main.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise14_45.h" 2 | 3 | int main() 4 | { 5 | Sales_data cp5("C++ Primer 5th", 4, 106.5); 6 | std::cout << cp5 << std::endl; 7 | std::cout << static_cast(cp5) << std::endl; 8 | std::cout << static_cast(cp5) << std::endl; 9 | } -------------------------------------------------------------------------------- /ch14/exercise14_5.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise14_5.h" 2 | 3 | std::istream& operator>>(std::istream &in, Book &book) 4 | { 5 | in >> book.no_ >> book.name_ >> book.author_ >> book.pubdate_; 6 | return in; 7 | } 8 | 9 | std::ostream& operator<<(std::ostream &out, const Book &book) 10 | { 11 | out << book.no_ << " " << book.name_ << " " << book.author_ << " " << book.pubdate_; 12 | return out; 13 | } 14 | 15 | bool operator==(const Book &lhs, const Book &rhs) 16 | { 17 | return lhs.no_ == rhs.no_; 18 | } 19 | 20 | bool operator!=(const Book &lhs, const Book &rhs) 21 | { 22 | return !(lhs == rhs); 23 | } -------------------------------------------------------------------------------- /ch14/exercise14_5.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_CH14_EX14_05_H 2 | #define CP5_CH14_EX14_05_H 3 | 4 | #include 5 | #include 6 | 7 | class Book 8 | { 9 | friend std::istream& operator>>(std::istream&, Book&); 10 | friend std::ostream& operator<<(std::ostream&, const Book&); 11 | friend bool operator==(const Book&, const Book&); 12 | friend bool operator!=(const Book&, const Book&); 13 | 14 | public: 15 | Book() = default; 16 | Book(unsigned no, std::string name, std::string author, std::string pubdate) :no_(no), name_(name), author_(author), pubdate_(pubdate) {} 17 | Book(std::istream &in) { in >> *this; } 18 | 19 | private: 20 | unsigned no_; 21 | std::string name_; 22 | std::string author_; 23 | std::string pubdate_; 24 | }; 25 | 26 | std::istream& operator>>(std::istream&, Book&); 27 | std::ostream& operator<<(std::ostream&, const Book&); 28 | bool operator==(const Book&, const Book&); 29 | bool operator!=(const Book&, const Book&); 30 | 31 | 32 | #endif // CP5_CH14_EX14_05_H -------------------------------------------------------------------------------- /ch14/exercise14_5_main.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise14_5.h" 2 | 3 | int main() 4 | { 5 | Book book1(123, "CP5", "Lippman", "2012"); 6 | Book book2(123, "CP5", "Lippman", "2012"); 7 | 8 | if (book1 == book2) 9 | std::cout << book1 << std::endl; 10 | } -------------------------------------------------------------------------------- /ch14/exercise14_7.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise14_7.h" 2 | #include 3 | #include 4 | 5 | std::pair 6 | String::alloc_n_copy(const char *b, const char *e) 7 | { 8 | auto str = alloc.allocate(e - b); 9 | return{ str, std::uninitialized_copy(b, e, str) }; 10 | } 11 | 12 | void String::range_initializer(const char *first, const char *last) 13 | { 14 | auto newstr = alloc_n_copy(first, last); 15 | elements = newstr.first; 16 | end = newstr.second; 17 | } 18 | 19 | String::String(const char *s) 20 | { 21 | char *sl = const_cast(s); 22 | while (*sl) 23 | ++sl; 24 | range_initializer(s, ++sl); 25 | } 26 | 27 | String::String(const String& rhs) 28 | { 29 | range_initializer(rhs.elements, rhs.end); 30 | std::cout << "copy constructor" << std::endl; 31 | } 32 | 33 | void String::free() 34 | { 35 | if (elements) 36 | { 37 | std::for_each(elements, end, [this](char &c) { alloc.destroy(&c); }); 38 | alloc.deallocate(elements, end - elements); 39 | } 40 | } 41 | 42 | String::~String() 43 | { 44 | free(); 45 | } 46 | 47 | String& String::operator = (const String &rhs) 48 | { 49 | auto newstr = alloc_n_copy(rhs.elements, rhs.end); 50 | free(); 51 | elements = newstr.first; 52 | end = newstr.second; 53 | std::cout << "copy-assignment" << std::endl; 54 | return *this; 55 | } 56 | 57 | std::ostream& operator<<(std::ostream &os, const String &s) 58 | { 59 | char *c = const_cast(s.c_str()); 60 | while (*c) 61 | os << *c++; 62 | return os; 63 | } -------------------------------------------------------------------------------- /ch14/exercise14_7.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_CH14_EX07_H_ 2 | #define CP5_CH14_EX07_H_ 3 | 4 | #include 5 | #include 6 | 7 | class String 8 | { 9 | friend std::ostream& operator<<(std::ostream&, const String&); 10 | public: 11 | String() : String("") {} 12 | String(const char *); 13 | String(const String&); 14 | String& operator=(const String&); 15 | ~String(); 16 | 17 | const char *c_str() const { return elements; } 18 | size_t size() const { return end - elements; } 19 | size_t length() const { return end - elements - 1; } 20 | 21 | private: 22 | std::pair alloc_n_copy(const char*, const char*); 23 | void range_initializer(const char*, const char*); 24 | void free(); 25 | 26 | private: 27 | char *elements; 28 | char *end; 29 | std::allocator alloc; 30 | }; 31 | 32 | std::ostream& operator<<(std::ostream&, const String&); 33 | 34 | #endif //CP5_CH14_EX07_H_ -------------------------------------------------------------------------------- /ch14/exercise14_7_main.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise14_7.h" 2 | 3 | int main() 4 | { 5 | String str("Hello World"); 6 | std::cout << str << std::endl; 7 | } -------------------------------------------------------------------------------- /ch15/Bulk_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef BULK_QUOTE_H_ 2 | #define BULK_QUOTE_H_ 3 | #include "Disc_quote.h" 4 | 5 | class Bulk_quote : public Disc_quote 6 | { 7 | public: 8 | Bulk_quote() = default; 9 | Bulk_quote(const std::string& b, double p, std::size_t q, double disc) : 10 | Disc_quote(b, p, q, disc) 11 | {} 12 | 13 | double net_price(std::size_t n) const override; 14 | }; 15 | 16 | #endif // BULK_QUOTE_H -------------------------------------------------------------------------------- /ch15/Disc_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef DISC_QUOTE_H 2 | #define DISC_QUOTE_H 3 | 4 | #include "exercise15_5.h" 5 | 6 | class Disc_quote : public Quote 7 | { 8 | public: 9 | Disc_quote(); 10 | Disc_quote(const std::string& b, double p, std::size_t q, double d) : 11 | Quote(b, p), quantity(q), discount(d) 12 | {} 13 | 14 | virtual double net_price(std::size_t n) const override = 0; 15 | 16 | protected: 17 | std::size_t quantity; 18 | double discount; 19 | }; 20 | 21 | #endif // DISC_QUOTE_H -------------------------------------------------------------------------------- /ch15/Limit_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef LIMIT_QUOTE_H 2 | #define LIMIT_QUOTE_H 3 | 4 | #include "disc_quote.h" 5 | 6 | class Limit_quote : public Disc_quote 7 | { 8 | public: 9 | Limit_quote() = default; 10 | Limit_quote(const std::string& b, double p, std::size_t max, double disc) : 11 | Disc_quote(b, p, max, disc) 12 | {} 13 | 14 | double net_price(std::size_t n) const override 15 | { 16 | return n * price * (n < quantity ? 1 - discount : 1); 17 | } 18 | 19 | }; 20 | 21 | #endif // LIMIT_QUOTE_H -------------------------------------------------------------------------------- /ch15/basket.cpp: -------------------------------------------------------------------------------- 1 | #include "basket.h" 2 | double Basket::total_receipt(std::ostream &os) const 3 | { 4 | double sum = 0.0; 5 | 6 | for (auto iter = items.cbegin(); iter != items.cend(); 7 | iter = items.upper_bound(*iter)) 8 | // ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 9 | // @note this increment moves iter to the first element with key 10 | // greater than *iter. 11 | 12 | { 13 | sum += print_total(os, **iter, items.count(*iter)); 14 | } // ^^^^^^^^^^^^^ using count to fetch 15 | // the number of the same book. 16 | os << "Total Sale: " << sum << std::endl; 17 | return sum; 18 | } -------------------------------------------------------------------------------- /ch15/basket.h: -------------------------------------------------------------------------------- 1 | #ifndef BASKET_H 2 | #define BASKET_H 3 | 4 | #include "quote.h" 5 | #include 6 | #include 7 | 8 | 9 | // a basket of objects from Quote hierachy, using smart pointers. 10 | class Basket 11 | { 12 | public: 13 | // copy verison 14 | void add_item(const Quote& sale) 15 | { 16 | items.insert(std::shared_ptr(sale.clone())); 17 | } 18 | // move version 19 | void add_item(Quote&& sale) 20 | { 21 | items.insert(std::shared_ptr(std::move(sale).clone())); 22 | } 23 | 24 | double total_receipt(std::ostream& os) const; 25 | 26 | private: 27 | 28 | // function to compare needed by the multiset member 29 | static bool compare(const std::shared_ptr& lhs, 30 | const std::shared_ptr& rhs) 31 | { 32 | return lhs->isbn() < rhs->isbn(); 33 | } 34 | 35 | // hold multiple quotes, ordered by the compare member 36 | std::multiset, decltype(compare)*> 37 | items{ compare }; 38 | }; 39 | 40 | #endif // BASKET_H -------------------------------------------------------------------------------- /ch15/exercise15_20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "exercise15_5.h" 5 | #include "bulk_quote.h" 6 | #include "limit_quote.h" 7 | #include "disc_quote.h" 8 | 9 | class Base 10 | { 11 | public: 12 | void pub_mem(); // public member 13 | protected: 14 | int prot_mem; // protected member 15 | private: 16 | char priv_mem; // private member 17 | }; 18 | 19 | struct Pub_Derv : public Base 20 | { 21 | void memfcn(Base &b) { b = *this; } 22 | }; 23 | struct Priv_Derv : private Base 24 | { 25 | void memfcn(Base &b) { b = *this; } 26 | }; 27 | struct Prot_Derv : protected Base 28 | { 29 | void memfcn(Base &b) { b = *this; } 30 | }; 31 | 32 | struct Derived_from_Public : public Pub_Derv 33 | { 34 | void memfcn(Base &b) { b = *this; } 35 | }; 36 | struct Derived_from_Private : public Priv_Derv 37 | { 38 | //void memfcn(Base &b) { b = *this; } 39 | }; 40 | struct Derived_from_Protected : public Prot_Derv 41 | { 42 | void memfcn(Base &b) { b = *this; } 43 | }; 44 | 45 | int main() 46 | { 47 | Pub_Derv d1; 48 | Base *p = &d1; 49 | 50 | Priv_Derv d2; 51 | //p = &d2; 52 | 53 | Prot_Derv d3; 54 | //p = &d3; 55 | 56 | Derived_from_Public dd1; 57 | p = &dd1; 58 | 59 | Derived_from_Private dd2; 60 | //p =& dd2; 61 | 62 | Derived_from_Protected dd3; 63 | //p = &dd3; 64 | 65 | 66 | return 0; 67 | } -------------------------------------------------------------------------------- /ch15/exercise15_26.h: -------------------------------------------------------------------------------- 1 | #ifndef QUOTE_H 2 | #define QUOTE_H 3 | 4 | #include 5 | #include 6 | 7 | class Quote 8 | { 9 | friend bool operator !=(const Quote& lhs, const Quote& rhs); 10 | public: 11 | Quote() { std::cout << "default constructing Quote\n"; } 12 | Quote(const std::string &b, double p) : 13 | bookNo(b), price(p) 14 | { 15 | std::cout << "Quote : constructor taking 2 parameters\n"; 16 | } 17 | 18 | // copy constructor 19 | Quote(const Quote& q) : bookNo(q.bookNo), price(q.price) 20 | { 21 | std::cout << "Quote: copy constructing\n"; 22 | } 23 | 24 | // move constructor 25 | Quote(Quote&& q) noexcept : bookNo(std::move(q.bookNo)), price(std::move(q.price)) 26 | { std::cout << "Quote: move constructing\n"; } 27 | 28 | // copy = 29 | Quote& operator =(const Quote& rhs) 30 | { 31 | if (*this != rhs) 32 | { 33 | bookNo = rhs.bookNo; 34 | price = rhs.price; 35 | } 36 | std::cout << "Quote: copy =() \n"; 37 | 38 | return *this; 39 | } 40 | 41 | // move = 42 | Quote& operator =(Quote&& rhs) noexcept 43 | { 44 | if (*this != rhs) 45 | { 46 | bookNo = std::move(rhs.bookNo); 47 | price = std::move(rhs.price); 48 | } 49 | std::cout << "Quote: move =!!!!!!!!! \n"; 50 | 51 | return *this; 52 | } 53 | 54 | std::string isbn() const { return bookNo; } 55 | virtual double net_price(std::size_t n) const { return n * price; } 56 | virtual void debug() const; 57 | 58 | virtual ~Quote() 59 | { 60 | std::cout << "destructing Quote\n"; 61 | } 62 | 63 | private: 64 | std::string bookNo; 65 | 66 | protected: 67 | double price = 10.0; 68 | }; 69 | 70 | bool inline 71 | operator !=(const Quote& lhs, const Quote& rhs) 72 | { 73 | return lhs.bookNo != rhs.bookNo 74 | && 75 | lhs.price != rhs.price; 76 | } 77 | 78 | #endif // QUOTE_H -------------------------------------------------------------------------------- /ch15/exercise15_26_2.h: -------------------------------------------------------------------------------- 1 | #ifndef BULK_QUOTE_H 2 | #define BULK_QUOTE_H 3 | #include "Disc_quote.h" 4 | #include 5 | 6 | class Bulk_quote : public Disc_quote 7 | { 8 | 9 | public: 10 | Bulk_quote() { std::cout << "default constructing Bulk_quote\n"; } 11 | Bulk_quote(const std::string& b, double p, std::size_t q, double disc) : 12 | Disc_quote(b, p, q, disc) 13 | { 14 | std::cout << "Bulk_quote : constructor taking 4 parameters\n"; 15 | } 16 | 17 | // copy constructor 18 | Bulk_quote(const Bulk_quote& bq) : Disc_quote(bq) 19 | { 20 | std::cout << "Bulk_quote : copy constructor\n"; 21 | } 22 | 23 | // move constructor 24 | Bulk_quote(Bulk_quote&& bq) : Disc_quote(std::move(bq)) noexcept 25 | { 26 | std::cout << "Bulk_quote : move constructor\n"; 27 | } 28 | 29 | // copy =() 30 | Bulk_quote& operator =(const Bulk_quote& rhs) 31 | { 32 | Disc_quote::operator =(rhs); 33 | std::cout << "Bulk_quote : copy =()\n"; 34 | 35 | return *this; 36 | } 37 | 38 | 39 | // move =() 40 | Bulk_quote& operator =(Bulk_quote&& rhs) noexcept 41 | { 42 | Disc_quote::operator =(std::move(rhs)); 43 | std::cout << "Bulk_quote : move =()\n"; 44 | 45 | return *this; 46 | } 47 | 48 | double net_price(std::size_t n) const override; 49 | void debug() const override; 50 | 51 | ~Bulk_quote() override 52 | { 53 | std::cout << "destructing Bulk_quote\n"; 54 | } 55 | }; 56 | 57 | 58 | 59 | #endif // BULK_QUOTE_H -------------------------------------------------------------------------------- /ch15/exercise15_27.h: -------------------------------------------------------------------------------- 1 | #ifndef BULK_QUOTE_H 2 | #define BULK_QUOTE_H 3 | #include "disc_quote.h" 4 | #include 5 | 6 | class Bulk_quote : public Disc_quote 7 | { 8 | 9 | public: 10 | Bulk_quote() { std::cout << "default constructing Bulk_quote\n"; } 11 | 12 | // changed the below to the inherited constructor for ex15.27. 13 | // rules: 1. only inherit from the direct base class. 14 | // 2. default, copy and move constructors can not inherit. 15 | // 3. any data members of its own are default initialized. 16 | // 4. the rest details are in the section section 15.7.4. 17 | /* 18 | Bulk_quote(const std::string& b, double p, std::size_t q, double disc) : 19 | Disc_quote(b, p, q, disc) { std::cout << "Bulk_quote : constructor taking 4 parameters\n"; } 20 | */ 21 | using Disc_quote::Disc_quote; 22 | 23 | // copy constructor 24 | Bulk_quote(const Bulk_quote& bq) : Disc_quote(bq) 25 | { 26 | std::cout << "Bulk_quote : copy constructor\n"; 27 | } 28 | 29 | // move constructor 30 | Bulk_quote(Bulk_quote&& bq) : Disc_quote(std::move(bq)) 31 | { 32 | std::cout << "Bulk_quote : move constructor\n"; 33 | } 34 | 35 | // copy =() 36 | Bulk_quote& operator =(const Bulk_quote& rhs) 37 | { 38 | Disc_quote::operator =(rhs); 39 | std::cout << "Bulk_quote : copy =()\n"; 40 | 41 | return *this; 42 | } 43 | 44 | 45 | // move =() 46 | Bulk_quote& operator =(Bulk_quote&& rhs) 47 | { 48 | Disc_quote::operator =(std::move(rhs)); 49 | std::cout << "Bulk_quote : move =()\n"; 50 | 51 | return *this; 52 | } 53 | 54 | double net_price(std::size_t n) const override; 55 | void debug() const override; 56 | 57 | ~Bulk_quote() override 58 | { 59 | std::cout << "destructing Bulk_quote\n"; 60 | } 61 | }; 62 | 63 | 64 | 65 | #endif // BULK_QUOTE_H -------------------------------------------------------------------------------- /ch15/exercise15_28.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "quote.h" 7 | #include "bulk_quote.h" 8 | #include "limit_quote.h" 9 | #include "disc_quote.h" 10 | 11 | 12 | int main() 13 | { 14 | /** 15 | * @brief ex15.28 outcome == 9090 16 | */ 17 | std::vector v; 18 | for (unsigned i = 1; i != 10; ++i) 19 | v.push_back(Bulk_quote("sss", i * 10.1, 10, 0.3)); 20 | 21 | double total = 0; 22 | for (const auto& b : v) 23 | { 24 | total += b.net_price(20); 25 | } 26 | std::cout << total << std::endl; 27 | 28 | std::cout << "======================\n\n"; 29 | 30 | /** 31 | * @brief ex15.29 outccome == 6363 32 | */ 33 | std::vector> pv; 34 | 35 | for (unsigned i = 1; i != 10; ++i) 36 | pv.push_back(std::make_shared(Bulk_quote("sss", i * 10.1, 10, 0.3))); 37 | 38 | double total_p = 0; 39 | for (auto p : pv) 40 | { 41 | total_p += p->net_price(20); 42 | } 43 | std::cout << total_p << std::endl; 44 | 45 | return 0; 46 | 47 | } -------------------------------------------------------------------------------- /ch15/exercise15_3.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise15_3.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | double print_total(std::ostream& os, const Quote& item, size_t n); 8 | 9 | int main() 10 | { 11 | 12 | 13 | return 0; 14 | } 15 | 16 | 17 | double print_total(std::ostream &os, const Quote &item, size_t n) 18 | { 19 | double ret = item.net_price(n); 20 | 21 | os << "ISBN:" << item.isbn() 22 | << "# sold: " << n << " total due: " << ret << std::endl; 23 | 24 | return ret; 25 | } -------------------------------------------------------------------------------- /ch15/exercise15_3.h: -------------------------------------------------------------------------------- 1 | #ifndef QUOTE_H 2 | #define QUOTE_H 3 | 4 | #include 5 | 6 | class Quote 7 | { 8 | public: 9 | Quote() = default; 10 | Quote(const std::string &b, double p) : 11 | bookNo(b), price(p) 12 | {} 13 | 14 | std::string isbn() const { return bookNo; } 15 | virtual double net_price(std::size_t n) const { return n * price; } 16 | 17 | virtual ~Quote() = default; 18 | 19 | private: 20 | std::string bookNo; 21 | 22 | protected: 23 | double price = 0.0; 24 | 25 | }; 26 | 27 | #endif // QUOTE_H -------------------------------------------------------------------------------- /ch15/exercise15_5.h: -------------------------------------------------------------------------------- 1 | #ifndef BULK_QUOTE_H 2 | #define BULK_QUOTE_H 3 | #include "exercise15_3.h" 4 | 5 | class Bulk_quote : public Quote 6 | { 7 | public: 8 | Bulk_quote() = default; 9 | Bulk_quote(const std::string& b, double p, std::size_t q, double disc) : 10 | Quote(b, p), min_qty(q), discount(disc) 11 | {} 12 | 13 | double net_price(std::size_t n) const override; 14 | 15 | private: 16 | std::size_t min_qty = 0; 17 | double discount = 0.0; 18 | }; 19 | 20 | #endif // BULK_QUOTE_H -------------------------------------------------------------------------------- /ch15/exercise15_6.cpp: -------------------------------------------------------------------------------- 1 | #include "exercise15_3.h" 2 | #include "exercise15_5.h" 3 | 4 | #include 5 | #include 6 | 7 | double print_total(std::ostream& os, const Quote& item, size_t n); 8 | 9 | int main() 10 | { 11 | // ex15.6 12 | Quote q("textbook", 10.60); 13 | Bulk_quote bq("textbook", 10.60, 10, 0.3); 14 | 15 | print_total(std::cout, q, 12); 16 | print_total(std::cout, bq, 12); 17 | 18 | return 0; 19 | } 20 | 21 | double print_total(std::ostream &os, const Quote &item, size_t n) 22 | { 23 | double ret = item.net_price(n); 24 | 25 | os << "ISBN:" << item.isbn() 26 | << "# sold: " << n << " total due: " << ret << std::endl; 27 | 28 | return ret; 29 | } -------------------------------------------------------------------------------- /ch15/exercise15_7.h: -------------------------------------------------------------------------------- 1 | #ifndef LIMIT_QUOTE_H 2 | #define LIMIT_QUOTE_H 3 | 4 | #include "exercise15_5.h" 5 | 6 | class Limit_quote : public Quote 7 | { 8 | public: 9 | Limit_quote(); 10 | Limit_quote(const std::string& b, double p, std::size_t max, double disc) : 11 | Quote(b, p), max_qty(max), discount(disc) 12 | {} 13 | 14 | double net_price(std::size_t n) const override; 15 | 16 | private: 17 | std::size_t max_qty = 0; 18 | double discount = 0.0; 19 | }; 20 | 21 | double Limit_quote::net_price(std::size_t n) const 22 | { 23 | if (n > max_qty) 24 | return max_qty * price * discount + (n - max_qty) * price; 25 | else 26 | return n * discount *price; 27 | } 28 | 29 | #endif // LIMIT_QUOTE_H -------------------------------------------------------------------------------- /ch15/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "quote.h" 8 | #include "bulk_quote.h" 9 | #include "limit_quote.h" 10 | #include "disc_quote.h" 11 | #include "basket.h" 12 | 13 | 14 | int main() 15 | { 16 | Basket basket; 17 | 18 | for (unsigned i = 0; i != 10; ++i) 19 | basket.add_item(Bulk_quote("Bible", 20.6, 20, 0.3)); 20 | 21 | for (unsigned i = 0; i != 10; ++i) 22 | basket.add_item(Bulk_quote("C++Primer", 30.9, 5, 0.4)); 23 | 24 | for (unsigned i = 0; i != 10; ++i) 25 | basket.add_item(Quote("CLRS", 40.1)); 26 | 27 | std::ofstream log("log.txt", std::ios_base::app | std::ios_base::out); 28 | 29 | basket.total_receipt(log); 30 | return 0; 31 | } -------------------------------------------------------------------------------- /ch15/query.h: -------------------------------------------------------------------------------- 1 | #ifndef QUERY_H 2 | #define QUERY_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "query_base.h" 8 | #include "queryresult.h" 9 | #include "textquery.h" 10 | #include "wordquery.h" 11 | 12 | 13 | 14 | /** 15 | * @brief interface class to manage the Query_base inheritance hierachy 16 | */ 17 | class Query 18 | { 19 | friend Query operator~(const Query&); 20 | friend Query operator|(const Query&, const Query&); 21 | friend Query operator&(const Query&, const Query&); 22 | public: 23 | // build a new WordQuery 24 | Query(const std::string& s) : q(new WordQuery(s)) 25 | { 26 | std::cout << "Query::Query(const std::string& s) where s=" + s + "\n"; 27 | } 28 | 29 | // interface functions: call the corresponding Query_base operatopns 30 | QueryResult eval(const TextQuery& t) const 31 | { 32 | return q->eval(t); 33 | } 34 | std::string rep() const 35 | { 36 | std::cout << "Query::rep() \n"; 37 | return q->rep(); 38 | } 39 | 40 | private: 41 | // constructor only for friends 42 | Query(std::shared_ptr query) : 43 | q(query) 44 | { 45 | std::cout << "Query::Query(std::shared_ptr query)\n"; 46 | } 47 | std::shared_ptr q; 48 | }; 49 | 50 | inline std::ostream& 51 | operator << (std::ostream& os, const Query& query) 52 | { 53 | // make a virtual call through its Query_base pointer to rep(); 54 | return os << query.rep(); 55 | } 56 | 57 | #endif // QUERY_H -------------------------------------------------------------------------------- /ch15/query_base.h: -------------------------------------------------------------------------------- 1 | #ifndef QUERY_BASE_H 2 | #define QUERY_BASE_H 3 | #include "textquery.h" 4 | #include "queryresult.h" 5 | 6 | /** 7 | * @brief abstract class acts as a base class for all concrete query types 8 | * all members are private. 9 | */ 10 | class Query_base 11 | { 12 | friend class Query; 13 | protected: 14 | using line_no = TextQuery::line_no; // used in the eval function 15 | virtual ~Query_base() = default; 16 | 17 | private: 18 | // returns QueryResult that matches this query 19 | virtual QueryResult eval(const TextQuery&) const = 0; 20 | 21 | // a string representation of this query 22 | virtual std::string rep() const = 0; 23 | }; 24 | 25 | #endif // QUERY_BASE_H -------------------------------------------------------------------------------- /ch16/blob.h: -------------------------------------------------------------------------------- 1 | #ifndef BLOB_H 2 | #define BLOB_H 3 | #include 4 | #include 5 | 6 | template class Blob 7 | { 8 | public: 9 | typedef T value_type; 10 | typedef typename std::vector::size_type size_type; 11 | 12 | // constructors 13 | Blob(); 14 | Blob(std::initializer_list il); 15 | 16 | // number of elements in the Blob 17 | size_type size() const { return data->size(); } 18 | bool empty() const { return data->empty(); } 19 | 20 | void push_back(const T& t) { data->push_back(t); } 21 | void push_back(T&& t) { data->push_back(std::move(t)); } 22 | void pop_back(); 23 | 24 | // element access 25 | T& back(); 26 | T& operator[](size_type i); 27 | 28 | const T& back() const; 29 | const T& operator [](size_type i) const; 30 | 31 | private: 32 | std::shared_ptr> data; 33 | // throw msg if data[i] isn't valid 34 | void check(size_type i, const std::string &msg) const; 35 | }; 36 | 37 | // constructors 38 | template 39 | Blob::Blob() : data(std::make_shared>()) 40 | {} 41 | 42 | template 43 | Blob::Blob(std::initializer_list il) : 44 | data(std::make_shared>(il)) 45 | {} 46 | 47 | template 48 | void Blob::check(size_type i, const std::string &msg) const 49 | { 50 | if (i >= data->size()) 51 | throw std::out_of_range(msg); 52 | } 53 | 54 | template 55 | T& Blob::back() 56 | { 57 | check(0, "back on empty Blob"); 58 | return data->back(); 59 | } 60 | 61 | template 62 | const T& Blob::back() const 63 | { 64 | check(0, "back on empty Blob"); 65 | return data->back(); 66 | } 67 | 68 | 69 | template 70 | T& Blob::operator [](size_type i) 71 | { 72 | // if i is too big, check function will throw, preventing access to a nonexistent element 73 | check(i, "subscript out of range"); 74 | return (*data)[i]; 75 | } 76 | 77 | 78 | template 79 | const T& Blob::operator [](size_type i) const 80 | { 81 | // if i is too big, check function will throw, preventing access to a nonexistent element 82 | check(i, "subscript out of range"); 83 | return (*data)[i]; 84 | } 85 | 86 | template 87 | void Blob::pop_back() 88 | { 89 | check(0, "pop_back on empty Blob"); 90 | data->pop_back(); 91 | } 92 | 93 | #endif // BLOB_H -------------------------------------------------------------------------------- /ch16/debugDelete.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUGDELETE_H 2 | #define DEBUGDELETE_H 3 | 4 | #include 5 | 6 | class DebugDelete 7 | { 8 | public: 9 | DebugDelete(std::ostream& s = std::cerr) : os(s) {} 10 | template 11 | void operator() (T* p) const 12 | { 13 | os << "deleting unique_ptr" << std::endl; 14 | delete p; 15 | } 16 | 17 | private: 18 | std::ostream& os; 19 | }; 20 | #endif // DEBUGDELETE_H -------------------------------------------------------------------------------- /ch16/delete.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace cp5 4 | { 5 | struct Delete 6 | { 7 | template 8 | auto operator() (T* p) const 9 | { 10 | delete p; 11 | } 12 | }; 13 | } -------------------------------------------------------------------------------- /ch16/screen.h: -------------------------------------------------------------------------------- 1 | #ifndef SCREEN_H 2 | #define SCREEN_H 3 | 4 | #include 5 | #include 6 | 7 | template 8 | class Screen 9 | { 10 | public: 11 | typedef std::string::size_type pos; 12 | Screen() = default; // needed because Screen has another constructor 13 | // cursor initialized to 0 by its in-class initializer 14 | Screen(char c) :contents(H * W, c) {} 15 | char get() const // get the character at the cursor 16 | { 17 | return contents[cursor]; 18 | } // implicitly inline 19 | Screen &move(pos r, pos c); // can be made inline later 20 | 21 | friend std::ostream & operator<< (std::ostream &os, const Screen & c) 22 | { 23 | unsigned int i, j; 24 | for (i = 0; i> (std::istream &is, Screen & c) 32 | { 33 | char a; 34 | is >> a; 35 | std::string temp(H*W, a); 36 | c.contents = temp; 37 | return is; 38 | } 39 | private: 40 | pos cursor = 0; 41 | pos height = H, width = W; 42 | std::string contents; 43 | }; 44 | 45 | template 46 | inline Screen& Screen::move(pos r, pos c) 47 | { 48 | pos row = r * width; 49 | cursor = row + c; 50 | return *this; 51 | } 52 | #endif // SCREEN_H -------------------------------------------------------------------------------- /data/books.txt: -------------------------------------------------------------------------------- 1 | 0-201-78345-X 3 20 2 | 0-201-78345-X 2 25 3 | 0-201-78346-X 1 100 4 | 0-201-78346-X 2 99.9 5 | 0-201-78346-X 6 89.9 -------------------------------------------------------------------------------- /data/exercise1_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangmingchuan/Cpp_Primer_Answers/925506ca53f7b2e8501bc8eaaee3dba8c03d9ec2/data/exercise1_17.png -------------------------------------------------------------------------------- /data/exercise1_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangmingchuan/Cpp_Primer_Answers/925506ca53f7b2e8501bc8eaaee3dba8c03d9ec2/data/exercise1_2.png -------------------------------------------------------------------------------- /data/exercise1_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangmingchuan/Cpp_Primer_Answers/925506ca53f7b2e8501bc8eaaee3dba8c03d9ec2/data/exercise1_24.png -------------------------------------------------------------------------------- /data/exercise1_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangmingchuan/Cpp_Primer_Answers/925506ca53f7b2e8501bc8eaaee3dba8c03d9ec2/data/exercise1_7.png -------------------------------------------------------------------------------- /data/exercise2_42.h: -------------------------------------------------------------------------------- 1 | #ifndef EXERCISE2_42 2 | #define EXERCISE2_42 3 | 4 | #include 5 | #include 6 | 7 | struct Sales_data 8 | { 9 | std::string bookNo; 10 | unsigned units_sold = 0; 11 | double revenue = 0.0; 12 | 13 | void CalcRevenue(double price); 14 | double CalcAveragePrice(); 15 | void SetData(Sales_data data); 16 | void AddData(Sales_data data); 17 | void Print(); 18 | }; 19 | 20 | void Sales_data::CalcRevenue(double price) 21 | { 22 | revenue = units_sold * price; 23 | } 24 | 25 | void Sales_data::SetData(Sales_data data) 26 | { 27 | bookNo = data.bookNo; 28 | units_sold = data.units_sold; 29 | revenue = data.revenue; 30 | } 31 | 32 | void Sales_data::AddData(Sales_data data) 33 | { 34 | if (bookNo != data.bookNo) return; 35 | units_sold += data.units_sold; 36 | revenue += data.revenue; 37 | } 38 | 39 | double Sales_data::CalcAveragePrice() 40 | { 41 | if (units_sold != 0) 42 | return revenue / units_sold; 43 | else 44 | return 0.0; 45 | } 46 | 47 | void Sales_data::Print() 48 | { 49 | std::cout << bookNo << " " << units_sold << " " << revenue << " "; 50 | double averagePrice = CalcAveragePrice(); 51 | if (averagePrice != 0.0) 52 | std::cout << averagePrice << std::endl; 53 | else 54 | std::cout << "(no sales)" << std::endl; 55 | } 56 | 57 | #endif -------------------------------------------------------------------------------- /data/for_transform.txt: -------------------------------------------------------------------------------- 1 | where r u 2 | y dont u send me a pic 3 | k thk l8r -------------------------------------------------------------------------------- /data/letter.txt: -------------------------------------------------------------------------------- 1 | In typography, an ascender is the portion of a minuscule letter in a Latin-derived alphabet that extends above the mean line of a font. That is, the part of a lower-case letter that is taller than the font's x-height. 2 | 3 | Ascenders, together with descenders, increase the recognizability of words. For this reason, British road signs no longer use all capital letters.[1] 4 | 5 | Studies made at the start of the construction of the British motorway network concluded that words with mixed-case letters were much easier to read than "all-caps" and a special font was designed for motorway signs. These then became universal across the U.K. See Road signs in the United Kingdom. -------------------------------------------------------------------------------- /data/phonenumbers.txt: -------------------------------------------------------------------------------- 1 | morgan 2015552368 8625550123 2 | drew 9735550130 3 | lee 6095550132 2015550175 8005550000 -------------------------------------------------------------------------------- /data/storyDataFile.txt: -------------------------------------------------------------------------------- 1 | Alice Emma has long flowing red hair. 2 | Her Daddy says when the wind blows 3 | through her hair, it looks almost alive, 4 | like a fiery bird in flight. 5 | A beautiful fiery bird, he tells her, 6 | magical but untamed. 7 | "Daddy, shush, there is no such thing," 8 | she tells him, at the same time wanting 9 | him to tell her more. 10 | Shyly, she asks, "I mean, Daddy, is there?" -------------------------------------------------------------------------------- /data/transform_rules.txt: -------------------------------------------------------------------------------- 1 | brb be right back 2 | k okay? 3 | y why 4 | r are 5 | u you 6 | pic picture 7 | thk thanks! 8 | l8r later --------------------------------------------------------------------------------