├── .clang-format ├── .github └── issue_template.md ├── .gitignore ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── ch01 ├── README.md ├── ex1_09.cpp ├── ex1_10.cpp ├── ex1_11.cpp ├── ex1_20.cpp ├── ex1_21.cpp ├── ex1_22.cpp └── ex1_23.cpp ├── ch02 ├── README.md ├── ex2_04.cpp ├── ex2_34.cpp ├── ex2_35.cpp ├── ex2_42_1.cpp ├── ex2_42_2.cpp ├── ex2_42_3.cpp └── ex2_42_sales_data.h ├── ch03 ├── README.md ├── ex3_01a.cpp ├── ex3_01b.cpp ├── ex3_02a.cpp ├── ex3_02b.cpp ├── ex3_04a.cpp ├── ex3_04b.cpp ├── ex3_05a.cpp ├── ex3_05b.cpp ├── ex3_06.cpp ├── ex3_08.cpp ├── ex3_10.cpp ├── ex3_14.cpp ├── ex3_15.cpp ├── ex3_16.cpp ├── ex3_17.cpp ├── ex3_18.cpp ├── ex3_19.cpp ├── ex3_20.cpp ├── ex3_21.cpp ├── ex3_22.cpp ├── ex3_23.cpp ├── ex3_24.cpp ├── ex3_25.cpp ├── ex3_31.cpp ├── ex3_32.cpp ├── ex3_35.cpp ├── ex3_36.cpp ├── ex3_39.cpp ├── ex3_40.cpp ├── ex3_41.cpp ├── ex3_42.cpp ├── ex3_43.cpp ├── ex3_44.cpp └── ex3_45.cpp ├── ch04 ├── README.md ├── ex4_21.cpp ├── ex4_22.cpp └── ex4_28.cpp ├── ch05 ├── README.md ├── ex5_05.cpp ├── ex5_06.cpp ├── ex5_09.cpp ├── ex5_10.cpp ├── ex5_11.cpp ├── ex5_12.cpp ├── ex5_14.cpp ├── ex5_17.cpp ├── ex5_19.cpp ├── ex5_20.cpp ├── ex5_21.cpp ├── ex5_23.cpp ├── ex5_24.cpp └── ex5_25.cpp ├── ch06 ├── Chapter6.h ├── README.md ├── ex6_04.cpp ├── ex6_10.cpp ├── ex6_11.cpp ├── ex6_12.cpp ├── ex6_17.cpp ├── ex6_21.cpp ├── ex6_22.cpp ├── ex6_23.cpp ├── ex6_25_26.cpp ├── ex6_27.cpp ├── ex6_33.cpp ├── ex6_42.cpp ├── ex6_44.cpp ├── ex6_47.cpp ├── ex6_51.cpp ├── ex6_54_55_56.cpp ├── fact.cc └── factMain.cc ├── ch07 ├── README.md ├── ex7_01.cpp ├── ex7_02_sales_data.h ├── ex7_03.cpp ├── ex7_04.h ├── ex7_05.h ├── ex7_06_sales_data.h ├── ex7_07.cpp ├── ex7_09.h ├── ex7_11_sales_data.cpp ├── ex7_11_sales_data.h ├── ex7_12_sales_data.h ├── ex7_13.cpp ├── ex7_15.h ├── ex7_21_sales_data.h ├── ex7_22.h ├── ex7_23.h ├── ex7_24.h ├── ex7_26_sales_data.cpp ├── ex7_26_sales_data.h ├── ex7_27.h ├── ex7_27_TEST.cpp ├── ex7_31.h ├── ex7_32.h ├── ex7_41_sales_data.cpp ├── ex7_41_sales_data.h ├── ex7_41_sales_data_test.cpp ├── ex7_43.cpp ├── ex7_50.h ├── ex7_53.h └── ex7_57.h ├── ch08 ├── README.md ├── ex8_02.cpp ├── ex8_04.cpp ├── ex8_05.cpp ├── ex8_06.cpp ├── ex8_07.cpp ├── ex8_08.cpp ├── ex8_09.cpp ├── ex8_10.cpp ├── ex8_11.cpp └── ex8_13.cpp ├── ch09 ├── README.md ├── ex9_13.cpp ├── ex9_14.cpp ├── ex9_15.cpp ├── ex9_16.cpp ├── ex9_18.cpp ├── ex9_19.cpp ├── ex9_20.cpp ├── ex9_22.cpp ├── ex9_24.cpp ├── ex9_26.cpp ├── ex9_27.cpp ├── ex9_28_TEST.cpp ├── ex9_31_1.cpp ├── ex9_31_2.cpp ├── ex9_32.cpp ├── ex9_33.cpp ├── ex9_34.cpp ├── ex9_38.cpp ├── ex9_41.cpp ├── ex9_43.cpp ├── ex9_44.cpp ├── ex9_45.cpp ├── ex9_46.cpp ├── ex9_47_1.cpp ├── ex9_47_2.cpp ├── ex9_49.cpp ├── ex9_50.cpp ├── ex9_51.cpp └── ex9_52.cpp ├── ch10 ├── README.md ├── ex10_01_02.cpp ├── ex10_03_04.cpp ├── ex10_05.cpp ├── ex10_06.cpp ├── ex10_07.cpp ├── ex10_09.cpp ├── ex10_11.cpp ├── ex10_12.cpp ├── ex10_13.cpp ├── ex10_16.cpp ├── ex10_17.cpp ├── ex10_18_19.cpp ├── ex10_20.cpp ├── ex10_21.cpp ├── ex10_22.cpp ├── ex10_24.cpp ├── ex10_25.cpp ├── ex10_27.cpp ├── ex10_28.cpp ├── ex10_29.cpp ├── ex10_30.cpp ├── ex10_31.cpp ├── ex10_32.cpp ├── ex10_33.cpp ├── ex10_34_35_36_37.cpp └── ex10_42.cpp ├── ch11 ├── README.md ├── ex11_11.cpp ├── ex11_12_13.cpp ├── ex11_14.cpp ├── ex11_18.cpp ├── ex11_20.cpp ├── ex11_23.cpp ├── ex11_24_25_26.cpp ├── ex11_27_28_29_30.cpp ├── ex11_31.cpp ├── ex11_32.cpp ├── ex11_33.cpp ├── ex11_38.cpp ├── ex11_3_4.cpp ├── ex11_7.cpp ├── ex11_8.cpp └── ex11_9_10.cpp ├── ch12 ├── README.md ├── ex12_02.h ├── ex12_02_TEST.cpp ├── ex12_06.cpp ├── ex12_07.cpp ├── ex12_10.cpp ├── ex12_11.cpp ├── ex12_12.cpp ├── ex12_13.cpp ├── ex12_14.cpp ├── ex12_15.cpp ├── ex12_16.cpp ├── ex12_17_18.cpp ├── ex12_19.cpp ├── ex12_19.h ├── ex12_20.cpp ├── ex12_22.cpp ├── ex12_22.h ├── ex12_23.cpp ├── ex12_24.cpp ├── ex12_26.cpp ├── ex12_27_30.cpp ├── ex12_27_30.h ├── ex12_27_30_TEST.cpp ├── ex12_28.cpp ├── ex12_32.cpp ├── ex12_32.h ├── ex12_33.cpp └── ex12_33.h ├── ch13 ├── README.md ├── ex13_05.h ├── ex13_08.h ├── ex13_11.h ├── ex13_13.cpp ├── ex13_17_1.cpp ├── ex13_17_2.cpp ├── ex13_17_3.cpp ├── ex13_18.cpp ├── ex13_18.h ├── ex13_19.h ├── ex13_22.h ├── ex13_26.cpp ├── ex13_26.h ├── ex13_27.h ├── ex13_28.cpp ├── ex13_28.h ├── ex13_30.h ├── ex13_31.h ├── ex13_34_36_37.cpp ├── ex13_34_36_37.h ├── ex13_34_36_37_TEST.cpp ├── ex13_39.cpp ├── ex13_39.h ├── ex13_40.cpp ├── ex13_40.h ├── ex13_42.cpp ├── ex13_42_StrVec.cpp ├── ex13_42_StrVec.h ├── ex13_42_TextQuery.cpp ├── ex13_42_TextQuery.h ├── ex13_44_47.cpp ├── ex13_44_47.h ├── ex13_48.cpp ├── ex13_49_Message.cpp ├── ex13_49_Message.h ├── ex13_49_Message_TEST.cpp ├── ex13_49_StrVec.cpp ├── ex13_49_StrVec.h ├── ex13_49_String.cpp ├── ex13_49_String.h ├── ex13_53.cpp ├── ex13_53.h ├── ex13_53_test.cpp └── ex13_58.cpp ├── ch14 ├── README.md ├── ex14_02_sales_data.cpp ├── ex14_02_sales_data.h ├── ex14_02_sales_data_test.cpp ├── ex14_05.cpp ├── ex14_05.h ├── ex14_05_TEST.cpp ├── ex14_07.cpp ├── ex14_07.h ├── ex14_07_TEST.cpp ├── ex14_15.cpp ├── ex14_15.h ├── ex14_15_TEST.cpp ├── ex14_16_StrBlob.cpp ├── ex14_16_StrBlob.h ├── ex14_16_StrBlobTest.cpp ├── ex14_16_StrVec.cpp ├── ex14_16_StrVec.h ├── ex14_16_StrVecMain.cpp ├── ex14_16_String.cpp ├── ex14_16_String.h ├── ex14_16_StringMain.cpp ├── ex14_18_StrBlob.cpp ├── ex14_18_StrBlob.h ├── ex14_18_StrBlobTest.cpp ├── ex14_18_StrVec.cpp ├── ex14_18_StrVec.h ├── ex14_18_StrVecMain.cpp ├── ex14_18_String.cpp ├── ex14_18_String.h ├── ex14_18_StringMain.cpp ├── ex14_22_sales_data.cpp ├── ex14_22_sales_data.h ├── ex14_22_sales_data_test.cpp ├── ex14_23.cpp ├── ex14_23.h ├── ex14_23_TEST.cpp ├── ex14_24.cpp ├── ex14_24.h ├── ex14_24_TEST.cpp ├── ex14_26_StrBlob.cpp ├── ex14_26_StrBlob.h ├── ex14_26_StrBlobTest.cpp ├── ex14_26_StrVec.cpp ├── ex14_26_StrVec.h ├── ex14_26_StrVecMain.cpp ├── ex14_26_String.cpp ├── ex14_26_String.h ├── ex14_26_StringMain.cpp ├── ex14_27_28_StrBlob.cpp ├── ex14_27_28_StrBlob.h ├── ex14_27_28_StrBlobTest.cpp ├── ex14_30_StrBlob.cpp ├── ex14_30_StrBlob.h ├── ex14_30_StrBlobTest.cpp ├── ex14_32.cpp ├── ex14_32.h ├── ex14_35.cpp ├── ex14_36.cpp ├── ex14_37.cpp ├── ex14_38_39.cpp ├── ex14_40.cpp ├── ex14_42.cpp ├── ex14_43.cpp ├── ex14_44.cpp ├── ex14_45_sales_data.cpp ├── ex14_45_sales_data.h ├── ex14_45_sales_data_test.cpp ├── ex14_49.cpp ├── ex14_49.h └── ex14_49_TEST.cpp ├── ch15 ├── README.md ├── TEST.cpp ├── ex15.34.35.36.38 │ ├── StrBlob.h │ ├── andquery.cpp │ ├── andquery.h │ ├── binaryquery.cpp │ ├── binaryquery.h │ ├── main.cpp │ ├── notquery.cpp │ ├── notquery.h │ ├── orquery.cpp │ ├── orquery.h │ ├── query.cpp │ ├── query.h │ ├── query_base.cpp │ ├── query_base.h │ ├── queryresult.cpp │ ├── queryresult.h │ ├── textquery.cpp │ ├── textquery.h │ ├── wordquery.cpp │ └── wordquery.h ├── ex15.39.40 │ ├── StrBlob.h │ ├── andquery.cpp │ ├── andquery.h │ ├── binaryquery.cpp │ ├── binaryquery.h │ ├── main.cpp │ ├── notquery.cpp │ ├── notquery.h │ ├── orquery.cpp │ ├── orquery.h │ ├── query.cpp │ ├── query.h │ ├── query_base.cpp │ ├── query_base.h │ ├── queryresult.cpp │ ├── queryresult.h │ ├── textquery.cpp │ ├── textquery.h │ ├── wordquery.cpp │ └── wordquery.h ├── ex15.42_b │ ├── andquery.cpp │ ├── andquery.h │ ├── binaryquery.cpp │ ├── binaryquery.h │ ├── main.cpp │ ├── notquery.cpp │ ├── notquery.h │ ├── orquery.cpp │ ├── orquery.h │ ├── query.cpp │ ├── query.h │ ├── query_base.cpp │ ├── query_base.h │ ├── queryhistory.cpp │ ├── queryhistory.h │ ├── queryresult.cpp │ ├── queryresult.h │ ├── test.txt │ ├── textquery.cpp │ ├── textquery.h │ ├── wordquery.cpp │ └── wordquery.h ├── ex15.42_c │ ├── andquery.cpp │ ├── andquery.h │ ├── binaryquery.cpp │ ├── binaryquery.h │ ├── main.cpp │ ├── notquery.cpp │ ├── notquery.h │ ├── orquery.cpp │ ├── orquery.h │ ├── query.cpp │ ├── query.h │ ├── query_base.cpp │ ├── query_base.h │ ├── queryresult.cpp │ ├── queryresult.h │ ├── test.txt │ ├── textquery.cpp │ ├── textquery.h │ ├── wordquery.cpp │ └── wordquery.h ├── ex15_03_Quote.h ├── ex15_05_Bulk_quote.h ├── ex15_07_Limit_quote.h ├── ex15_11_Bulk_quote.h ├── ex15_11_Limit_quote.h ├── ex15_11_Quote.h ├── ex15_15_Bulk_quote.h ├── ex15_15_Disc_quote.h ├── ex15_16_Limit_quote.h ├── ex15_20_Base.h ├── ex15_21_GeomtricPrimitives.h ├── ex15_23.cpp ├── ex15_26_Bulk_quote.h ├── ex15_26_Quote.h ├── ex15_27_Bulk_quote.h ├── ex15_30_Basket.h └── ex15_30_Quote_Bulk_quote.h ├── ch16 ├── README.md ├── ex16.48 │ └── main.cpp ├── ex16.49.50 │ └── main.cpp ├── ex16.51.52 │ └── main.cpp ├── ex16.53.54.55 │ └── main.cpp ├── ex16.56.57 │ └── main.cpp ├── ex16.58.59 │ ├── strvec.cpp │ ├── strvec.h │ └── vec.h ├── ex16.60.61 │ └── main.cpp ├── ex16.62 │ ├── Sales_data.cc │ ├── Sales_data.h │ └── main.cpp ├── ex16.63.64 │ └── main.cpp ├── ex16.65.66.67 │ └── main.cpp ├── ex16_02_compare.h ├── ex16_04_find.h ├── ex16_05_print_array.h ├── ex16_06_begin_end.h ├── ex16_07_sizeof_array.h ├── ex16_12_blob.h ├── ex16_12_blob_test.cpp ├── ex16_14_screen.h ├── ex16_14_screen_test.cpp ├── ex16_16_vec.h ├── ex16_16_vec_test.cpp ├── ex16_19_print_container.cpp ├── ex16_20_print_container_iter.cpp ├── ex16_21_debugdelete.cpp ├── ex16_21_debugdelete.h ├── ex16_22_textquery.cpp ├── ex16_22_textquery.h ├── ex16_22_textquery_test.cpp ├── ex16_24_blob.h ├── ex16_24_blob_test.cpp ├── ex16_28_shared_ptr.h ├── ex16_28_test.cpp ├── ex16_28_unique_ptr.h ├── ex16_29_blob.h ├── ex16_29_blob_test.cpp ├── ex16_41_sum.cpp ├── ex16_47_flip.cpp ├── ex16_50_overload_template.cpp └── ex16_52_variadic_template.cpp ├── ch17 ├── README.md ├── ex17.17.18 │ └── main.cpp ├── ex17.19.20 │ └── main.cpp ├── ex17.21 │ ├── data │ │ └── record.txt │ └── main.cpp ├── ex17.22 │ └── ex17.22 │ │ └── main.cpp ├── ex17.28.29.30 │ └── main.cpp ├── ex17_03_text_query.cpp ├── ex17_03_text_query.h ├── ex17_03_text_query_test.cpp ├── ex17_04_findBook.h ├── ex17_05_findBook.h ├── ex17_06_findBook.h ├── ex17_10.cpp ├── ex17_11_quiz_responses.h ├── ex17_11_quiz_responses_test.cpp ├── ex17_14.cpp ├── ex17_15.cpp ├── ex17_findBook_test.cpp └── ex_33.cpp ├── ch18 ├── README.md ├── ex18.1.2.3 │ └── main.cpp ├── ex18.12.13.14 │ └── main.cpp └── ex18.15.16.17 │ └── main.cpp ├── data ├── book.txt ├── even.txt ├── given_to_transform.txt ├── input.txt ├── letter.txt ├── odd.txt ├── phonenumbers.txt ├── store1 ├── store2 ├── store3 ├── store4 ├── storyDataFile.txt ├── word_transformation.txt └── word_transformation_bad.txt ├── generate_format_command.py └── include ├── Sales_item.h └── catch.hpp /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | ### Exercise information 2 | 3 | 7 | Exercise xx.xx 8 | 9 | ### Question or Bug 10 | 11 | 14 | 15 | ### Your enviroment information 16 | 17 | - **System**: :grey_question: 18 | - **Compiler version/IDE**: :grey_question: 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #vscode 2 | launch.json 3 | 4 | # Mac OS 5 | .DS_Store 6 | 7 | # LLVM 8 | *.dSYM 9 | 10 | # Compiled Object files 11 | *.slo 12 | *.lo 13 | *.o 14 | *.obj 15 | 16 | # Precompiled Headers 17 | *.gch 18 | *.pch 19 | 20 | # Compiled Dynamic libraries 21 | *.so 22 | *.dylib 23 | *.dll 24 | 25 | # Fortran module files 26 | *.mod 27 | 28 | # Compiled Static libraries 29 | *.lai 30 | *.la 31 | *.a 32 | *.lib 33 | 34 | # Executables 35 | *.exe 36 | *.out 37 | *.app 38 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "(gdb) Launch", 6 | "type": "cppdbg", 7 | "request": "launch", 8 | "program": "${file}.exe", 9 | "args": [], 10 | "stopAtEntry": false, 11 | "cwd": "${workspaceRoot}", 12 | "environment": [], 13 | "externalConsole": true, 14 | "MIMode": "gdb", 15 | "miDebuggerPath": "D:\\libs\\MinGW\\bin\\gdb.exe", 16 | "setupCommands": [ 17 | { 18 | "description": "Enable pretty-printing for gdb", 19 | "text": "-enable-pretty-printing", 20 | "ignoreFailures": true 21 | } 22 | ], 23 | "preLaunchTask": "g++" 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "0.1.0", 5 | "command": "g++", 6 | "args": [ 7 | "-g", 8 | "${file}", 9 | "-o", 10 | "${file}.exe", 11 | "-std=c++11", 12 | "-pedantic", 13 | "-Wall" 14 | ], 15 | "showOutput": "always", 16 | "isShellCommand": true, 17 | "problemMatcher": { 18 | "owner": "cpp", 19 | "fileLocation": [ 20 | "relative", 21 | "${workspaceRoot}" 22 | ], 23 | "pattern": { 24 | "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", 25 | "file": 1, 26 | "line": 2, 27 | "column": 3, 28 | "severity": 4, 29 | "message": 5 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /ch01/ex1_09.cpp: -------------------------------------------------------------------------------- 1 | // sum the numbers from 50 to 100 (use while) 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | int sum = 0, val = 50; 8 | while (val <= 100) { 9 | sum += val; 10 | ++val; 11 | } 12 | 13 | std::cout << "the sum is: " << sum << std::endl; 14 | 15 | return 0; 16 | } 17 | 18 | // output: the sum is: 3825 19 | -------------------------------------------------------------------------------- /ch01/ex1_10.cpp: -------------------------------------------------------------------------------- 1 | // prints the numbers from ten down to zero.(use while) 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | int val = 10; 8 | while (val >= 0) { 9 | std::cout << val << std::endl; 10 | --val; 11 | } 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /ch01/ex1_11.cpp: -------------------------------------------------------------------------------- 1 | // Print each number in the range specified by two integers. 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | int small = 0, big = 0; 8 | std::cout << "please input two integers:"; 9 | std::cin >> small >> big; 10 | 11 | if (small > big) { 12 | int tmp = small; 13 | small = big; 14 | big = tmp; 15 | } 16 | 17 | while (small <= big) { 18 | std::cout << small << " "; 19 | ++small; 20 | } 21 | std::cout << std::endl; 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch01/ex1_20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../include/Sales_item.h" 3 | 4 | int main() 5 | { 6 | Sales_item item; 7 | while (std::cin >> item) std::cout << item << std::endl; 8 | 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /ch01/ex1_21.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../include/Sales_item.h" 3 | 4 | int main() 5 | { 6 | Sales_item item1, item2; 7 | std::cin >> item1 >> item2; 8 | if (item1.isbn() == item2.isbn()) { 9 | std::cout << item1 + item2 << std::endl; 10 | return 0; 11 | } 12 | else { 13 | std::cerr << "Data must refer to same ISBN." << std::endl; 14 | return -1; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ch01/ex1_22.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../include/Sales_item.h" 3 | 4 | int main() 5 | { 6 | Sales_item total; 7 | if (std::cin >> total) { 8 | Sales_item trans; 9 | while (std::cin >> trans) { 10 | if (total.isbn() == trans.isbn()) 11 | total += trans; 12 | else { 13 | std::cout << total << std::endl; 14 | total = trans; 15 | } 16 | } 17 | std::cout << total << std::endl; 18 | } 19 | else { 20 | std::cerr << "No data?!" << std::endl; 21 | return -1; 22 | } 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /ch01/ex1_23.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../include/Sales_item.h" 3 | 4 | int main() 5 | { 6 | Sales_item currItem, valItem; 7 | if (std::cin >> currItem) { 8 | int cnt = 1; 9 | while (std::cin >> valItem) { 10 | if (valItem.isbn() == currItem.isbn()) 11 | ++cnt; 12 | else { 13 | std::cout << currItem << " occurs " << cnt << " times " 14 | << std::endl; 15 | currItem = valItem; 16 | cnt = 1; 17 | } 18 | } 19 | 20 | std::cout << currItem << " occurs " << cnt << " times " << std::endl; 21 | } 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch02/ex2_04.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 | } 16 | -------------------------------------------------------------------------------- /ch02/ex2_34.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | int i = 0, &r = i; 6 | auto a = r; // a is an int (r is an alias for i, which has type int) 7 | 8 | const int ci = i, &cr = ci; 9 | auto b = ci; // b is an int (top-level const in ci is dropped) 10 | auto c = cr; // c is an int (cr is an alias for ci whose const is top-level) 11 | auto d = &i; // d is an int* (& ofan int objectis int*) 12 | auto e = &ci; // e is const int*(& of a const object is low-level const) 13 | 14 | const auto f = ci; // deduced type of ci is int; f has type const int 15 | auto& g = ci; // g is a const int& that is bound to ci 16 | 17 | a = 42; 18 | b = 42; 19 | c = 42; 20 | *d = 42; 21 | e = &c; 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch02/ex2_42_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ex2_42_sales_data.h" 4 | 5 | int main() 6 | { 7 | Sales_data book; 8 | double price; 9 | std::cin >> book.bookNo >> book.units_sold >> price; 10 | book.CalcRevenue(price); 11 | book.Print(); 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /ch02/ex2_42_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ex2_42_sales_data.h" 4 | 5 | int main() 6 | { 7 | Sales_data book1, book2; 8 | double price1, price2; 9 | std::cin >> book1.bookNo >> book1.units_sold >> price1; 10 | std::cin >> book2.bookNo >> book2.units_sold >> price2; 11 | book1.CalcRevenue(price1); 12 | book2.CalcRevenue(price2); 13 | 14 | if (book1.bookNo == book2.bookNo) { 15 | book1.AddData(book2); 16 | book1.Print(); 17 | 18 | return 0; 19 | } 20 | else { 21 | std::cerr << "Data must refer to same ISBN" << std::endl; 22 | return -1; // indicate failure 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ch02/ex2_42_3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ex2_42_sales_data.h" 4 | 5 | int main() 6 | { 7 | Sales_data total; 8 | double totalPrice; 9 | if (std::cin >> total.bookNo >> total.units_sold >> totalPrice) { 10 | total.CalcRevenue(totalPrice); 11 | 12 | Sales_data trans; 13 | double transPrice; 14 | while (std::cin >> trans.bookNo >> trans.units_sold >> transPrice) { 15 | trans.CalcRevenue(transPrice); 16 | 17 | if (total.bookNo == trans.bookNo) { 18 | total.AddData(trans); 19 | } 20 | else { 21 | total.Print(); 22 | total.SetData(trans); 23 | } 24 | } 25 | 26 | total.Print(); 27 | 28 | return 0; 29 | } 30 | else { 31 | std::cerr << "No data?!" << std::endl; 32 | return -1; // indicate failure 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ch03/ex3_01a.cpp: -------------------------------------------------------------------------------- 1 | // use `using` for 1.4.1 2 | 3 | #include 4 | 5 | using std::cin; 6 | using std::cout; 7 | using std::endl; 8 | 9 | int main() 10 | { 11 | int sum = 0, val = 1; 12 | // keep executing the while as long as val is less than or equal to 10 13 | while (val <= 10) { 14 | sum += val; 15 | ++val; 16 | } 17 | cout << "Sum of 1 to 10 inclusive is " << sum << endl; 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /ch03/ex3_02a.cpp: -------------------------------------------------------------------------------- 1 | // read the standard input a line at a time. 2 | #include 3 | #include 4 | 5 | using std::string; 6 | using std::cin; 7 | using std::cout; 8 | using std::endl; 9 | using std::getline; 10 | 11 | int main() 12 | { 13 | string input; 14 | while (getline(cin, input)) cout << input << endl; 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /ch03/ex3_02b.cpp: -------------------------------------------------------------------------------- 1 | // read the standard input a word at a time 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 word; 13 | while (cin >> word) cout << word << endl; 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /ch03/ex3_04a.cpp: -------------------------------------------------------------------------------- 1 | // read two strings and report whether the strings are equal 2 | // If not, report which of the two is larger. 3 | #include 4 | #include 5 | 6 | using std::string; 7 | using std::cin; 8 | using std::cout; 9 | using std::endl; 10 | 11 | int main() 12 | { 13 | string str1, str2; 14 | while (cin >> str1 >> str2) { 15 | if (str1 == str2) 16 | cout << "The two strings are equal." << endl; 17 | else 18 | cout << "The larger string is " << ((str1 > str2) ? str1 : str2); 19 | } 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch03/ex3_04b.cpp: -------------------------------------------------------------------------------- 1 | // read two strings and report whether the strings have the same length 2 | // If not, report which is longer 3 | #include 4 | #include 5 | 6 | using std::string; 7 | using std::cin; 8 | using std::cout; 9 | using std::endl; 10 | 11 | int main() 12 | { 13 | string str1, str2; 14 | while (cin >> str1 >> str2) { 15 | if (str1.size() == str2.size()) 16 | cout << "The two strings have the same length." << endl; 17 | else 18 | cout << "The longer string is " 19 | << ((str1.size() > str2.size()) ? str1 : str2); 20 | } 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch03/ex3_05a.cpp: -------------------------------------------------------------------------------- 1 | // read strings from the standard input, concatenating what is read into one 2 | // large string. 3 | // Print the concatenated string. 4 | #include 5 | #include 6 | 7 | using std::string; 8 | using std::cin; 9 | using std::cout; 10 | using std::endl; 11 | 12 | int main() 13 | { 14 | string largeStr; 15 | string str; 16 | while (cin >> str) { 17 | largeStr += str; 18 | } 19 | 20 | cout << "The concatenated string is " << largeStr << endl; 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch03/ex3_05b.cpp: -------------------------------------------------------------------------------- 1 | // separate adjacent input strings by a space. 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 largeStr; 13 | string str; 14 | while (cin >> str) { 15 | if (largeStr.empty()) 16 | largeStr += str; 17 | else 18 | largeStr += " " + str; 19 | } 20 | 21 | cout << "The concatenated string is " << largeStr << endl; 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch03/ex3_06.cpp: -------------------------------------------------------------------------------- 1 | // Use a range for to change all the characters in a string to X. 2 | 3 | #include 4 | #include 5 | 6 | using std::string; 7 | using std::cout; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | string str("a simple string"); 13 | for (auto& c : str) c = 'X'; 14 | cout << str << endl; 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /ch03/ex3_08.cpp: -------------------------------------------------------------------------------- 1 | // Use a range for to change all the characters in a string to X. 2 | 3 | #include 4 | #include 5 | 6 | using std::string; 7 | using std::cout; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | string str("a simple string"); 13 | // use while 14 | decltype(str.size()) i = 0; 15 | while (i < str.size()) { 16 | str[i] = 'X'; 17 | ++i; 18 | } 19 | cout << str << endl; 20 | 21 | // use traditional for 22 | for (i = 0; i < str.size(); ++i) str[i] = 'Y'; 23 | cout << str << endl; 24 | 25 | // I like the first one. 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /ch03/ex3_10.cpp: -------------------------------------------------------------------------------- 1 | // reads a string of characters including punctuation and writes what was read 2 | // but with the punctuation removed. 3 | 4 | #include 5 | #include 6 | 7 | using std::string; 8 | using std::cout; 9 | using std::cin; 10 | using std::endl; 11 | 12 | int main() 13 | { 14 | string s; 15 | cout << "Enter a string of characters including punctuation." << endl; 16 | while (getline(cin, s)) { 17 | for (auto i : s) 18 | if (!ispunct(i)) cout << i; 19 | cout << endl; 20 | } 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch03/ex3_14.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | ///@Author PEZY 3 | ///@Date Aug. 2014 4 | ///@Brief 5 | /// read a sequence of ints from cin and 6 | /// store those values in a vector. 7 | /// 8 | 9 | #include 10 | #include 11 | 12 | int main() 13 | { 14 | std::vector vec; 15 | int i; 16 | while (std::cin >> i) vec.push_back(i); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /ch03/ex3_15.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | ///@Author PEZY 3 | ///@Date Aug. 2014 4 | ///@Brief 5 | /// read a sequence of strings from cin and 6 | /// store those values in a vector. 7 | /// 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | int main() 14 | { 15 | std::vector vec; 16 | std::string str; 17 | while (std::cin >> str) vec.push_back(str); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ch03/ex3_18.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::vector; 4 | 5 | int main() 6 | { 7 | vector ivec{0}; 8 | ivec[0] = 42; 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /ch03/ex3_19.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | ///@Author PEZY 3 | ///@Date Aug. 2014 4 | ///@Brief 5 | /// List three ways to define a vector and give it ten elements, 6 | /// each with the value 42. 7 | /// Indicate whether there is a preferred way to do so and why. 8 | 9 | #include 10 | #include 11 | using std::vector; 12 | 13 | int main() 14 | { 15 | vector ivec1(10, 42); 16 | vector ivec2{42, 42, 42, 42, 42, 42, 42, 42, 42, 42}; 17 | vector ivec3; 18 | for (int i = 0; i != 10; ++i) ivec3.push_back(42); 19 | std::cout << "The first approach is better!" << std::endl; 20 | } 21 | -------------------------------------------------------------------------------- /ch03/ex3_20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::vector; 5 | using std::cout; 6 | using std::endl; 7 | using std::cin; 8 | 9 | int main() 10 | { 11 | vector ivec; 12 | int i; 13 | while (cin >> i) ivec.push_back(i); 14 | 15 | if (ivec.empty()) { 16 | cout << "input at least one integer." << endl; 17 | return -1; 18 | } 19 | else if (ivec.size() == 1) { 20 | cout << ivec[0] << " don't have any adjacent elements."; 21 | } 22 | else { 23 | for (decltype(ivec.size()) i = 0; i != ivec.size() - 1; ++i) 24 | cout << ivec[i] + ivec[i + 1] << " "; 25 | } 26 | 27 | cout << endl; 28 | 29 | decltype(ivec.size()) size = ivec.size(); 30 | if (size % 2 != 0) 31 | size = size / 2 + 1; 32 | else 33 | size /= 2; 34 | 35 | for (decltype(ivec.size()) i = 0; i != size; ++i) 36 | cout << ivec[i] + ivec[ivec.size() - i - 1] << " "; 37 | cout << endl; 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /ch03/ex3_22.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Revise the loop that printed the first paragraph in text 3 | /// to instead change the elements in text that correspond 4 | /// to the first paragraph to all uppercase. 5 | /// After you’ve updated text, print its contents. 6 | /// 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using std::vector; 14 | using std::string; 15 | using std::cout; 16 | using std::cin; 17 | using std::endl; 18 | 19 | int main() 20 | { 21 | vector text; 22 | for (string line; getline(cin, line);) text.push_back(line); 23 | 24 | for (auto it = text.begin(); it != text.end() && !it->empty(); ++it) { 25 | for (auto& c : *it) c = toupper(c); 26 | cout << *it << endl; 27 | } 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /ch03/ex3_23.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Write a program to create a vector with ten int elements. 3 | /// Using an iterator, assign each element a value that is twice its current 4 | /// value. 5 | /// Test your program by printing the vector. 6 | /// 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using std::vector; 13 | using std::iterator; 14 | using std::cout; 15 | using std::endl; 16 | 17 | int main() 18 | { 19 | vector ivec(10, 1); 20 | for (auto it = ivec.begin(); it != ivec.end(); ++it) *it *= 2; 21 | for (auto value : ivec) cout << value << " "; 22 | cout << endl; 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /ch03/ex3_24.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::vector; 6 | using std::cout; 7 | using std::endl; 8 | using std::cin; 9 | 10 | int main() 11 | { 12 | int i; 13 | vector ivec; 14 | while (cin >> i) ivec.push_back(i); 15 | 16 | if (ivec.empty()) { 17 | cout << "input at least one integer." << endl; 18 | return -1; 19 | } 20 | else if (ivec.size() == 1) { 21 | cout << *ivec.begin() << " has no adjacent elements."; 22 | } 23 | 24 | for (auto it = ivec.begin(); it + 1 != ivec.end(); ++it) 25 | cout << *it + *(it + 1) << " "; 26 | cout << endl; 27 | 28 | for (auto beg = ivec.begin(), end = ivec.end() - 1; beg <= end; 29 | ++beg, --end) 30 | cout << *beg + *end << " "; 31 | cout << endl; 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /ch03/ex3_25.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::vector; 6 | using std::cout; 7 | using std::cin; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | vector scores(11, 0); 13 | unsigned grade; 14 | while (cin >> grade) 15 | if (grade <= 100) ++(*(scores.begin() + grade / 10)); 16 | 17 | for (auto score : scores) cout << score << " "; 18 | cout << endl; 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /ch03/ex3_31.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::cout; 5 | using std::endl; 6 | 7 | int main() 8 | { 9 | int ia[10]; 10 | for (size_t i = 0; i < 10; ++i) ia[i] = i; 11 | 12 | for (auto i : ia) cout << i << " "; 13 | cout << endl; 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /ch03/ex3_32.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using std::cout; 7 | using std::endl; 8 | using std::vector; 9 | using std::iterator; 10 | 11 | int main() 12 | { 13 | // use array 14 | int ia[10]; 15 | for (size_t i = 0; i < 10; ++i) ia[i] = i; 16 | 17 | int ia2[10]; 18 | for (size_t i = 0; i < 10; ++i) ia2[i] = ia[i]; 19 | 20 | // use vector 21 | vector iv(10); 22 | for (auto iter = iv.begin(); iter != iv.end(); ++iter) 23 | *iter = iter - iv.begin(); 24 | 25 | vector iv2(iv); 26 | 27 | for (auto i : iv2) cout << i << " "; 28 | cout << endl; 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /ch03/ex3_35.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::begin; 5 | using std::end; 6 | using std::cout; 7 | using std::endl; 8 | 9 | int main() 10 | { 11 | int arr[10]; 12 | int* b = begin(arr); 13 | int* e = end(arr); 14 | 15 | for (int* i = b; i != e; ++i) *i = 0; 16 | 17 | for (auto i : arr) cout << i << " "; 18 | cout << endl; 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /ch03/ex3_39.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::cout; 6 | using std::endl; 7 | using std::string; 8 | 9 | int main() 10 | { 11 | // use string. 12 | string s1("Mooophy"); 13 | string s2("Pezy"); 14 | 15 | if (s1 == s2) 16 | cout << "same string." << endl; 17 | else if (s1 > s2) 18 | cout << "Mooophy > Pezy" << endl; 19 | else 20 | cout << "Mooophy < Pezy" << endl; 21 | 22 | cout << "=========" << endl; 23 | // use C-Style character strings. 24 | const char* cs1 = "Wangyue"; 25 | const char* cs2 = "Pezy"; 26 | 27 | auto result = strcmp(cs1, cs2); 28 | if (result == 0) 29 | cout << "same string." << endl; 30 | else if (result < 0) 31 | cout << "Wangyue < Pezy" << endl; 32 | else 33 | cout << "Wangyue > Pezy" << endl; 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /ch03/ex3_40.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to define two character arrays initialized 2 | // from string literals. Now define a third character array to hold the 3 | // concatenation of the two arrays. Use `strcpy` and `strcat` to copy the two 4 | // arrays into the third. 5 | 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::endl; 11 | 12 | int main() 13 | { 14 | const char cstr1[] = "Hello"; 15 | const char cstr2[] = "world!"; 16 | 17 | size_t new_size = strlen(cstr1) + strlen(" ") + strlen(cstr2) + 1; 18 | char* cstr3 = new char[new_size]; 19 | 20 | strcpy(cstr3, cstr1); 21 | strcat(cstr3, " "); 22 | strcat(cstr3, cstr2); 23 | 24 | std::cout << cstr3 << std::endl; 25 | delete [] cstr3; 26 | } 27 | -------------------------------------------------------------------------------- /ch03/ex3_41.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::vector; 5 | using std::cout; 6 | using std::endl; 7 | using std::begin; 8 | using std::end; 9 | 10 | int main() 11 | { 12 | int int_arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 13 | vector ivec(begin(int_arr), end(int_arr)); 14 | 15 | for (auto i : ivec) cout << i << " "; 16 | cout << endl; 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /ch03/ex3_42.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::vector; 5 | using std::cout; 6 | using std::endl; 7 | using std::begin; 8 | using std::end; 9 | 10 | int main() 11 | { 12 | vector ivec{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 13 | int int_arr[10]; 14 | 15 | for (int* i = begin(int_arr); i != end(int_arr); ++i) 16 | *i = ivec[i - begin(int_arr)]; 17 | 18 | for (auto i : int_arr) cout << i << " "; 19 | cout << endl; 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch03/ex3_43.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 | // a range for to manage the iteration 11 | for (const int(&p)[4] : ia) 12 | for (int q : p) cout << q << " "; 13 | cout << endl; 14 | 15 | // ordinary for loop using subscripts 16 | for (size_t i = 0; i != 3; ++i) 17 | for (size_t j = 0; j != 4; ++j) cout << ia[i][j] << " "; 18 | cout << endl; 19 | 20 | // using pointers. 21 | for (int(*p)[4] = ia; p != ia + 3; ++p) 22 | for (int* q = *p; q != *p + 4; ++q) cout << *q << " "; 23 | cout << endl; 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch03/ex3_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 | // a range for to manage the iteration 11 | // use type alias 12 | using int_array = int[4]; 13 | for (int_array& p : ia) 14 | for (int q : p) cout << q << " "; 15 | cout << endl; 16 | 17 | // ordinary for loop using subscripts 18 | for (size_t i = 0; i != 3; ++i) 19 | for (size_t j = 0; j != 4; ++j) cout << ia[i][j] << " "; 20 | cout << endl; 21 | 22 | // using pointers. 23 | // use type alias 24 | for (int_array* p = ia; p != ia + 3; ++p) 25 | for (int* q = *p; q != *p + 4; ++q) cout << *q << " "; 26 | cout << endl; 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch03/ex3_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 | // a range for to manage the iteration 11 | for (auto& p : ia) 12 | for (int q : p) cout << q << " "; 13 | cout << endl; 14 | 15 | // ordinary for loop using subscripts 16 | for (size_t i = 0; i != 3; ++i) 17 | for (size_t j = 0; j != 4; ++j) cout << ia[i][j] << " "; 18 | cout << endl; 19 | 20 | // using pointers. 21 | for (auto p = ia; p != ia + 3; ++p) 22 | for (int* q = *p; q != *p + 4; ++q) cout << *q << " "; 23 | cout << endl; 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch04/ex4_21.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::vector ivec{1, 2, 3, 4, 5, 6, 7, 8, 9}; 7 | for (auto& i : ivec) i = (i % 2) ? (i * 2) : i; 8 | 9 | // Check 10 | for (auto i : ivec) std::cout << i << " "; 11 | std::cout << std::endl; 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /ch04/ex4_22.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::cout; 4 | using std::cin; 5 | using std::endl; 6 | 7 | int main() 8 | { 9 | unsigned grade; 10 | while (cin >> grade) { 11 | // first version(only use conditional operators) 12 | cout << ((grade > 90) ? "high pass" : (grade < 60) 13 | ? "fail" 14 | : (grade < 75) ? "low pass" 15 | : "pass"); 16 | cout << endl; 17 | // second version(only use if statements) 18 | if (grade > 90) 19 | cout << "high pass"; 20 | else if (grade < 60) 21 | cout << "fail"; 22 | else if (grade < 75) 23 | cout << "low pass"; 24 | else 25 | cout << "pass"; 26 | cout << endl; 27 | } 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /ch05/ex5_05.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::vector; 6 | using std::string; 7 | using std::cout; 8 | using std::endl; 9 | using std::cin; 10 | 11 | int main() 12 | { 13 | vector scores = {"F", "D", "C", "B", "A", "A++"}; 14 | 15 | int grade{0}; 16 | while (cin >> grade) { 17 | string lettergrade; 18 | if (grade < 60) 19 | lettergrade = scores[0]; 20 | else { 21 | lettergrade = scores[(grade - 50) / 10]; 22 | if (grade != 100) { 23 | if (grade % 10 > 7) 24 | lettergrade += "+"; 25 | else if (grade % 10 < 3) 26 | lettergrade += "-"; 27 | } 28 | } 29 | 30 | cout << lettergrade << endl; 31 | } 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /ch05/ex5_06.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::vector; 6 | using std::string; 7 | using std::cout; 8 | using std::endl; 9 | using std::cin; 10 | 11 | int main() 12 | { 13 | vector scores = {"F", "D", "C", "B", "A", "A++"}; 14 | 15 | int grade{0}; 16 | while (cin >> grade) { 17 | string lettergrade = grade < 60 ? scores[0] : scores[(grade - 50) / 10]; 18 | lettergrade += 19 | (grade == 100 || grade < 60) 20 | ? "" 21 | : (grade % 10 > 7) ? "+" : (grade % 10 < 3) ? "-" : ""; 22 | cout << lettergrade << endl; 23 | } 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch05/ex5_09.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::cout; 4 | using std::endl; 5 | using std::cin; 6 | 7 | int main() 8 | { 9 | unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0; 10 | char ch; 11 | while (cin >> ch) { 12 | if (ch == 'a') 13 | ++aCnt; 14 | else if (ch == 'e') 15 | ++eCnt; 16 | else if (ch == 'i') 17 | ++iCnt; 18 | else if (ch == 'o') 19 | ++oCnt; 20 | else if (ch == 'u') 21 | ++uCnt; 22 | } 23 | cout << "Number of vowel a: \t" << aCnt << '\n' << "Number of vowel e: \t" 24 | << eCnt << '\n' << "Number of vowel i: \t" << iCnt << '\n' 25 | << "Number of vowel o: \t" << oCnt << '\n' << "Number of vowel u: \t" 26 | << uCnt << endl; 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch05/ex5_10.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::cin; 3 | using std::cout; 4 | using std::endl; 5 | 6 | int main() 7 | { 8 | unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0; 9 | char ch; 10 | while (cin >> ch) switch (ch) { 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 | } 41 | -------------------------------------------------------------------------------- /ch05/ex5_17.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 vec1{0, 1, 1, 2}; 11 | vector vec2{0, 1, 1, 2, 3, 5, 8}; 12 | 13 | auto size = vec1.size() < vec2.size() ? vec1.size() : vec2.size(); 14 | for (decltype(vec1.size()) i = 0; i != size; ++i) { 15 | if (vec1[i] != vec2[i]) { 16 | cout << "false" << endl; 17 | return 0; 18 | } 19 | } 20 | cout << "true" << endl; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch05/ex5_19.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::cout; 5 | using std::cin; 6 | using std::endl; 7 | using std::string; 8 | 9 | int main() 10 | { 11 | string rsp; 12 | do { 13 | cout << "Input two strings: "; 14 | string str1, str2; 15 | cin >> str1 >> str2; 16 | cout << (str1 <= str2 ? str1 : str2) << " is less than the other. " 17 | << "\n\n" 18 | << "More? Enter yes or no: "; 19 | cin >> rsp; 20 | } while (!rsp.empty() && rsp[0] == 'y'); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch05/ex5_20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::cout; 5 | using std::cin; 6 | using std::endl; 7 | using std::string; 8 | 9 | int main() 10 | { 11 | string read, tmp; 12 | while (cin >> read) 13 | if (read == tmp) 14 | break; 15 | else 16 | tmp = read; 17 | 18 | if (cin.eof()) 19 | cout << "no word was repeated." << endl; 20 | else 21 | cout << read << " occurs twice in succession." << endl; 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch05/ex5_21.cpp: -------------------------------------------------------------------------------- 1 | // Revise the program from the exercise in 5.5.1(p. 191) 2 | // so that it looks only for duplicated words that start with an 3 | // uppercase letter. 4 | 5 | #include 6 | using std::cin; 7 | using std::cout; 8 | using std::endl; 9 | 10 | #include 11 | using std::string; 12 | 13 | int main() { 14 | string curr, prev; 15 | bool no_twice = false; 16 | 17 | while (cin >> curr) { 18 | if (!isupper(curr[0])) { 19 | prev = ""; 20 | continue; 21 | } 22 | if (prev == curr) { 23 | cout << curr << " occurs twice in succession." << endl; 24 | no_twice = true; 25 | break; 26 | } 27 | prev = curr; 28 | } 29 | 30 | if (!no_twice) cout << "no word was repeated." << endl; 31 | } 32 | -------------------------------------------------------------------------------- /ch05/ex5_23.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int a, b; 6 | std::cin >> a >> b; 7 | std::cout << static_cast(a) / b << std::endl; 8 | 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /ch05/ex5_24.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | int a, b; 7 | std::cin >> a >> b; 8 | 9 | if (b == 0) throw std::runtime_error("divisor is 0"); 10 | 11 | std::cout << static_cast(a) / b << std::endl; 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /ch05/ex5_25.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::cin; 4 | using std::cout; 5 | using std::endl; 6 | using std::runtime_error; 7 | 8 | int main(void) 9 | { 10 | int a, b; 11 | cout << "Input two integers: "; 12 | while (cin >> a >> b) { 13 | try { 14 | if (b == 0) throw runtime_error("divisor is 0"); 15 | cout << static_cast(a) / b << endl; 16 | cout << "Input two integers: "; 17 | } 18 | catch (runtime_error err) { 19 | cout << err.what() ; 20 | cout << "\nTry Again? Enter y or n:" << endl; 21 | char c; 22 | cin >> c; 23 | if (!cin || c == 'n') 24 | break; 25 | else 26 | cout << "Input two integers: "; 27 | } 28 | } 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /ch06/Chapter6.h: -------------------------------------------------------------------------------- 1 | int fact(int val); 2 | int func(); 3 | 4 | template T abs(T i) 5 | { 6 | return i >= 0 ? i : -i; 7 | } 8 | -------------------------------------------------------------------------------- /ch06/ex6_04.cpp: -------------------------------------------------------------------------------- 1 | // Write a function that interacts with the user, asking for a number and 2 | // generating the factorial of that number. Call this function from main. 3 | 4 | // About the magic number(13): https://github.com/Mooophy/Cpp-Primer/pull/172 5 | 6 | #include 7 | #include 8 | 9 | using std::cin; 10 | using std::cout; 11 | using std::endl; 12 | 13 | int fact(int val) 14 | { 15 | int ret = 1; 16 | while (val > 1) ret *= val--; 17 | return ret; 18 | } 19 | 20 | void factorial_with_interacts() 21 | { 22 | for (int val = 0; cout << "Enter a number within [0, 13): ", cin >> val;) { 23 | if (val < 0 || val > 12) continue; 24 | cout << val << "! =" << fact(val) << endl; 25 | } 26 | } 27 | 28 | int main() 29 | { 30 | factorial_with_interacts(); 31 | } -------------------------------------------------------------------------------- /ch06/ex6_10.cpp: -------------------------------------------------------------------------------- 1 | // Using pointers, write a function to swap the values of two ints. 2 | // Test the function by calling it and printing the swapped values. 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | using std::cin; 9 | using std::cout; 10 | using std::endl; 11 | 12 | void swap(int* const lhs, int* const rhs) 13 | { 14 | auto tmp = *lhs; 15 | *lhs = *rhs; 16 | *rhs = tmp; 17 | } 18 | 19 | int main() 20 | { 21 | for (int lht, rht; cout << "Please Enter:\n", cin >> lht >> rht;) { 22 | swap(&lht, &rht); 23 | cout << lht << " " << rht << endl; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ch06/ex6_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 | } 14 | -------------------------------------------------------------------------------- /ch06/ex6_12.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the program from exercise 6.10 in 6.2.1 (p. 210) to use 2 | // references instead of pointers to swap the value of two ints. Which 3 | // version do you think would be easier to use and why? 4 | // The version using reference is easier. 5 | 6 | #include 7 | #include 8 | 9 | using std::cin; 10 | using std::cout; 11 | using std::endl; 12 | 13 | void swap(int& lhs, int& rhs) 14 | { 15 | auto tmp = lhs; 16 | lhs = rhs; 17 | rhs = tmp; 18 | } 19 | 20 | int main() 21 | { 22 | for (int left, right; cout << "Please Enter:\n", cin >> left >> right;) { 23 | swap(left, right); 24 | cout << left << " " << right << endl; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ch06/ex6_17.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::string; 5 | 6 | bool hasUppercase(const string& str) 7 | { 8 | for (auto c : str) 9 | if (isupper(c)) return true; 10 | return false; 11 | } 12 | 13 | const string& makeLowercase(string& str) 14 | { 15 | for (auto& c : str) 16 | if (isupper(c)) c = tolower(c); 17 | return str; 18 | } 19 | 20 | int main() 21 | { 22 | string str("Hello World!"); 23 | std::cout << std::boolalpha << hasUppercase(str) << std::endl; 24 | std::cout << makeLowercase(str) << std::endl; 25 | } 26 | -------------------------------------------------------------------------------- /ch06/ex6_21.cpp: -------------------------------------------------------------------------------- 1 | // Write a function that takes an int and a pointer to an int and 2 | // returns the larger of the int value or the value to which the 3 | // pointer points. What type should you use for the pointer? 4 | 5 | #include 6 | 7 | int LargerOne(int i, const int* const ip) 8 | { 9 | return (i > *ip) ? i : *ip; 10 | } 11 | 12 | int main() 13 | { 14 | int c = 6; 15 | std::cout << LargerOne(7, &c) << std::endl; 16 | } 17 | -------------------------------------------------------------------------------- /ch06/ex6_22.cpp: -------------------------------------------------------------------------------- 1 | // Write a function to swap two int pointers. 2 | 3 | #include 4 | 5 | void swap(const int*& lhs, const int*& rhs) 6 | { 7 | auto temp = lhs; 8 | lhs = rhs; 9 | rhs = temp; 10 | } 11 | 12 | int main() 13 | { 14 | const int i = 42, j = 99; 15 | auto lhs = &i; 16 | auto rhs = &j; 17 | swap(lhs, rhs); 18 | std::cout << *lhs << " " << *rhs << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /ch06/ex6_25_26.cpp: -------------------------------------------------------------------------------- 1 | // Write a main function that takes two arguments. 2 | // Concatenate the supplied arguments and print the resulting string. 3 | 4 | // Write a program that accepts the options presented 5 | // in this section. Print the values of the arguments passed to main. 6 | 7 | #include 8 | #include 9 | 10 | int main(int argc, char** argv) 11 | { 12 | std::string str; 13 | for (int i = 1; i != argc; ++i) { 14 | str += argv[i]; 15 | str += " "; 16 | } 17 | 18 | std::cout << str << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /ch06/ex6_27.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int sum(const std::initializer_list& il) 5 | { 6 | int sum = 0; 7 | for (auto i : il) sum += i; 8 | return sum; 9 | } 10 | 11 | int main(void) 12 | { 13 | std::cout << sum({1, 2, 3, 4, 5}) << std::endl; 14 | } 15 | -------------------------------------------------------------------------------- /ch06/ex6_33.cpp: -------------------------------------------------------------------------------- 1 | // Write a recursive function to print the contents of a vector 2 | 3 | #include 4 | #include 5 | 6 | using std::cout; 7 | using std::vector; 8 | using Iter = vector::iterator; 9 | 10 | void print(Iter beg, Iter end) 11 | { 12 | if (beg != end) { 13 | cout << *beg << " "; 14 | print(std::next(beg), end); 15 | } 16 | } 17 | 18 | int main() 19 | { 20 | vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9}; 21 | print(vec.begin(), vec.end()); 22 | } 23 | -------------------------------------------------------------------------------- /ch06/ex6_42.cpp: -------------------------------------------------------------------------------- 1 | // Give the second parameter of make_plural (6.3.2, p. 224) a default 2 | // argument of 's'. Test your program by printing singular and plural versions 3 | // of the words success and failure. 4 | 5 | #include 6 | #include 7 | 8 | using std::cout; 9 | using std::endl; 10 | using std::string; 11 | 12 | string make_plural(size_t ctr, const string& word, const string& ending = "s") 13 | { 14 | return (ctr > 1) ? word + ending : word; 15 | } 16 | 17 | int main() 18 | { 19 | cout << "singual: " << make_plural(1, "success", "es") << " " 20 | << make_plural(1, "failure") << endl; 21 | cout << "plural : " << make_plural(2, "success", "es") << " " 22 | << make_plural(2, "failure") << endl; 23 | } 24 | -------------------------------------------------------------------------------- /ch06/ex6_44.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the isShorter function from 6.2.2 (p. 211) to be inline. 2 | 3 | #include 4 | #include 5 | 6 | using std::string; 7 | 8 | inline bool isShorter(const string& s1, const string& s2) 9 | { 10 | return s1.size() < s2.size(); 11 | } 12 | 13 | int main() 14 | { 15 | std::cout << isShorter("pezy", "mooophy") << std::endl; 16 | } 17 | -------------------------------------------------------------------------------- /ch06/ex6_47.cpp: -------------------------------------------------------------------------------- 1 | // Revise the program you wrote in the exercises in 6.3.2 (p. 2 | // 228) that used recursion to print the contents of a vector to conditionally 3 | // print information about its execution. For example, you might print the size 4 | // of the vector on each call. Compile and run the program with debugging turned 5 | // on and again with it turned off. 6 | 7 | #include 8 | #include 9 | using std::cout; 10 | using std::endl; 11 | using std::vector; 12 | 13 | //#define NDEBUG 14 | 15 | void printVec(vector& vec) 16 | { 17 | #ifndef NDEBUG 18 | cout << "vector size: " << vec.size() << endl; 19 | #endif 20 | if (!vec.empty()) { 21 | auto tmp = vec.back(); 22 | vec.pop_back(); 23 | printVec(vec); 24 | cout << tmp << " "; 25 | } 26 | } 27 | 28 | int main() 29 | { 30 | vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9}; 31 | printVec(vec); 32 | cout << endl; 33 | } 34 | -------------------------------------------------------------------------------- /ch06/ex6_51.cpp: -------------------------------------------------------------------------------- 1 | // Write all four versions of f. Each function should print a 2 | // distinguishing message. Check your answers for the previous exercise. If your 3 | // answers were incorrect, study this section until you understand why your 4 | // answers were wrong. 5 | 6 | #include 7 | using std::cout; 8 | using std::endl; 9 | 10 | void f() 11 | { 12 | cout << "f()" << endl; 13 | } 14 | 15 | void f(int) 16 | { 17 | cout << "f(int)" << endl; 18 | } 19 | 20 | void f(int, int) 21 | { 22 | cout << "f(int, int)" << endl; 23 | } 24 | 25 | void f(double, double) 26 | { 27 | cout << "f(double, double)" << endl; 28 | } 29 | 30 | int main() 31 | { 32 | // f(2.56, 42); // error: 'f' is ambiguous. 33 | f(42); 34 | f(42, 0); 35 | f(2.56, 3.14); 36 | } 37 | -------------------------------------------------------------------------------- /ch06/fact.cc: -------------------------------------------------------------------------------- 1 | #include "Chapter6.h" 2 | #include 3 | 4 | int fact(int val) 5 | { 6 | if (val == 0 || val == 1) 7 | return 1; 8 | else 9 | return val * fact(val - 1); 10 | } 11 | 12 | int func() 13 | { 14 | int n, ret = 1; 15 | std::cout << "input a number: "; 16 | std::cin >> n; 17 | while (n > 1) ret *= n--; 18 | return ret; 19 | } 20 | -------------------------------------------------------------------------------- /ch06/factMain.cc: -------------------------------------------------------------------------------- 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 | } 10 | -------------------------------------------------------------------------------- /ch07/ex7_01.cpp: -------------------------------------------------------------------------------- 1 | #include "../ch02/ex2_42_sales_data.h" 2 | 3 | int main() 4 | { 5 | Sales_data total; 6 | if (std::cin >> total.bookNo >> total.units_sold >> total.revenue) { 7 | Sales_data trans; 8 | while (std::cin >> trans.bookNo >> trans.units_sold >> trans.revenue) { 9 | if (total.bookNo == trans.bookNo) 10 | total.AddData(trans); 11 | else { 12 | total.Print(); 13 | total = trans; 14 | } 15 | } 16 | total.Print(); 17 | } 18 | else { 19 | std::cerr << "No data?!" << std::endl; 20 | return -1; 21 | } 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch07/ex7_02_sales_data.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex7_02_h 2 | #define CP5_ex7_02_h 3 | 4 | #include 5 | 6 | // Add the combine and isbn members to the Sales_data 7 | struct Sales_data { 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 24 | -------------------------------------------------------------------------------- /ch07/ex7_03.cpp: -------------------------------------------------------------------------------- 1 | #include "ex7_02_sales_data.h" 2 | #include 3 | 4 | using std::cin; 5 | using std::cout; 6 | using std::endl; 7 | 8 | int main() 9 | { 10 | Sales_data total; 11 | if (cin >> total.bookNo >> total.units_sold >> total.revenue) { 12 | Sales_data trans; 13 | while (cin >> trans.bookNo >> trans.units_sold >> trans.revenue) { 14 | if (total.isbn() == trans.isbn()) 15 | total.combine(trans); 16 | else { 17 | cout << total.bookNo << " " << total.units_sold << " " 18 | << total.revenue << endl; 19 | total = trans; 20 | } 21 | } 22 | cout << total.bookNo << " " << total.units_sold << " " << total.revenue 23 | << endl; 24 | } 25 | else { 26 | std::cerr << "No data?!" << std::endl; 27 | return -1; 28 | } 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /ch07/ex7_04.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_04.h 3 | // Exercise 7.4 4 | // 5 | // Created by pezy on 14/11/8. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_04_h 10 | #define CP5_ex7_04_h 11 | 12 | #include 13 | 14 | class Person { 15 | std::string name; 16 | std::string address; 17 | }; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /ch07/ex7_05.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_05.h 3 | // Exercise 7.5 4 | // 5 | // Created by pezy on 14/11/8. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_05_h 10 | #define CP5_ex7_05_h 11 | 12 | #include 13 | 14 | class Person { 15 | std::string name; 16 | std::string address; 17 | 18 | public: 19 | const std::string& getName() const { return name; } 20 | const std::string& getAddress() const { return address; } 21 | }; 22 | 23 | #endif 24 | 25 | // Should these functions be const? 26 | 27 | // Yes, A const following the parameter list indicates that this is a pointer to 28 | // const. 29 | // These functions my read but not write to the data members of the objects on 30 | // which it is called. 31 | -------------------------------------------------------------------------------- /ch07/ex7_07.cpp: -------------------------------------------------------------------------------- 1 | #include "ex7_06_sales_data.h" 2 | 3 | int main() 4 | { 5 | Sales_data total; 6 | if (read(std::cin, total)) { 7 | Sales_data trans; 8 | while (read(std::cin, trans)) { 9 | if (total.isbn() == trans.isbn()) 10 | total.combine(trans); 11 | else { 12 | print(std::cout, total) << std::endl; 13 | total = trans; 14 | } 15 | } 16 | print(std::cout, total) << std::endl; 17 | } 18 | else { 19 | std::cerr << "No data?!" << std::endl; 20 | return -1; 21 | } 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch07/ex7_09.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_09.h 3 | // Exercise 7.9 4 | // 5 | // Created by pezy on 11/8/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_09_h 10 | #define CP5_ex7_09_h 11 | 12 | #include 13 | #include 14 | 15 | struct Person { 16 | const std::string& getName() const { return name; } 17 | const 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 | if (!is) person = Person(); 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 37 | -------------------------------------------------------------------------------- /ch07/ex7_11_sales_data.cpp: -------------------------------------------------------------------------------- 1 | #include "ex7_11_sales_data.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 | -------------------------------------------------------------------------------- /ch07/ex7_13.cpp: -------------------------------------------------------------------------------- 1 | #include "ex7_12_sales_data.h" 2 | 3 | int main() 4 | { 5 | Sales_data total(std::cin); 6 | if (!total.isbn().empty()) { 7 | std::istream& is = std::cin; 8 | while (is) { 9 | Sales_data trans(is); 10 | if (total.isbn() == trans.isbn()) 11 | total.combine(trans); 12 | else { 13 | print(std::cout, total) << std::endl; 14 | total = trans; 15 | } 16 | } 17 | } 18 | else { 19 | std::cerr << "No data?!" << std::endl; 20 | return -1; 21 | } 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch07/ex7_15.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_15.h 3 | // Exercise 7.15 4 | // 5 | // Created by pezy on 11/9/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_15_h 10 | #define CP5_ex7_15_h 11 | 12 | #include 13 | #include 14 | 15 | struct Person; 16 | std::istream& read(std::istream&, Person&); 17 | 18 | struct Person { 19 | Person() = default; 20 | Person(const std::string sname, const std::string saddr) 21 | : name(sname), address(saddr) 22 | { 23 | } 24 | Person(std::istream& is) { read(is, *this); } 25 | 26 | std::string getName() const { return name; } 27 | std::string getAddress() const { return address; } 28 | 29 | std::string name; 30 | std::string address; 31 | }; 32 | 33 | std::istream& read(std::istream& is, Person& person) 34 | { 35 | is >> person.name >> person.address; 36 | return is; 37 | } 38 | 39 | std::ostream& print(std::ostream& os, const Person& person) 40 | { 41 | os << person.name << " " << person.address; 42 | return os; 43 | } 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /ch07/ex7_23.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_23.h 3 | // Exercise 7.23 4 | // 5 | // Created by pezy on 11/14/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_23_h 10 | #define CP5_ex7_23_h 11 | 12 | #include 13 | 14 | class Screen { 15 | public: 16 | using pos = std::string::size_type; 17 | 18 | Screen() = default; 19 | Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c) 20 | { 21 | } 22 | 23 | char get() const { return contents[cursor]; } 24 | char get(pos r, pos c) const { return contents[r * width + c]; } 25 | 26 | private: 27 | pos cursor = 0; 28 | pos height = 0, width = 0; 29 | std::string contents; 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /ch07/ex7_24.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_24.cpp 3 | // Exercise 7.24 4 | // 5 | // Created by pezy on 11/14/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_24_h 10 | #define CP5_ex7_24_h 11 | 12 | #include 13 | 14 | class Screen { 15 | public: 16 | using pos = std::string::size_type; 17 | 18 | Screen() = default; // 1 19 | Screen(pos ht, pos wd) : height(ht), width(wd), contents(ht * wd, ' ') {} // 2 20 | Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c) 21 | { 22 | } // 3 23 | 24 | char get() const { return contents[cursor]; } 25 | char get(pos r, pos c) const { return contents[r * width + c]; } 26 | 27 | private: 28 | pos cursor = 0; 29 | pos height = 0, width = 0; 30 | std::string contents; 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /ch07/ex7_26_sales_data.cpp: -------------------------------------------------------------------------------- 1 | #include "ex7_26_sales_data.h" 2 | 3 | // member functions. 4 | Sales_data& Sales_data::combine(const Sales_data& rhs) 5 | { 6 | units_sold += rhs.units_sold; 7 | revenue += rhs.revenue; 8 | return *this; 9 | } 10 | 11 | // friend functions 12 | std::istream& read(std::istream& is, Sales_data& item) 13 | { 14 | double price = 0; 15 | is >> item.bookNo >> item.units_sold >> price; 16 | item.revenue = price * item.units_sold; 17 | return is; 18 | } 19 | 20 | std::ostream& print(std::ostream& os, const Sales_data& item) 21 | { 22 | os << item.isbn() << " " << item.units_sold << " " << item.revenue; 23 | return os; 24 | } 25 | 26 | Sales_data add(const Sales_data& lhs, const Sales_data& rhs) 27 | { 28 | Sales_data sum = lhs; 29 | sum.combine(rhs); 30 | return sum; 31 | } 32 | -------------------------------------------------------------------------------- /ch07/ex7_27_TEST.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_27_TEST.cpp 3 | // Test of Exercise 7.27 4 | // 5 | // Created by pezy on 11/14/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #include "ex7_27.h" 10 | 11 | int main() 12 | { 13 | Screen myScreen(5, 5, 'X'); 14 | myScreen.move(4, 0).set('#').display(std::cout); 15 | std::cout << "\n"; 16 | myScreen.display(std::cout); 17 | std::cout << "\n"; 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ch07/ex7_31.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_31.h 3 | // Exercise 7.31 4 | // 5 | // Created by pezy on 11/17/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_31_h 10 | #define CP5_ex7_31_h 11 | 12 | class Y; 13 | 14 | class X { 15 | Y* y = nullptr; 16 | }; 17 | 18 | class Y { 19 | X x; 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /ch07/ex7_41_sales_data.cpp: -------------------------------------------------------------------------------- 1 | #include "ex7_41_sales_data.h" 2 | 3 | // constructor 4 | Sales_data::Sales_data(std::istream& is) : Sales_data() 5 | { 6 | std::cout << "Sales_data(istream &is)" << std::endl; 7 | read(is, *this); 8 | } 9 | 10 | // member functions. 11 | Sales_data& Sales_data::combine(const Sales_data& rhs) 12 | { 13 | units_sold += rhs.units_sold; 14 | revenue += rhs.revenue; 15 | return *this; 16 | } 17 | 18 | // friend functions 19 | std::istream& read(std::istream& is, Sales_data& item) 20 | { 21 | double price = 0; 22 | is >> item.bookNo >> item.units_sold >> price; 23 | item.revenue = price * item.units_sold; 24 | return is; 25 | } 26 | 27 | std::ostream& print(std::ostream& os, const Sales_data& item) 28 | { 29 | os << item.isbn() << " " << item.units_sold << " " << item.revenue; 30 | return os; 31 | } 32 | 33 | Sales_data add(const Sales_data& lhs, const Sales_data& rhs) 34 | { 35 | Sales_data sum = lhs; 36 | sum.combine(rhs); 37 | return sum; 38 | } 39 | -------------------------------------------------------------------------------- /ch07/ex7_43.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_43.cpp 3 | // Exercise 7.43 4 | // 5 | // Created by pezy on 11/20/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #include 10 | 11 | class NoDefault { 12 | public: 13 | NoDefault(int i) {} 14 | }; 15 | 16 | class C { 17 | public: 18 | C() : def(0) {} // define the constructor of C. 19 | private: 20 | NoDefault def; 21 | }; 22 | 23 | int main() 24 | { 25 | C c; 26 | 27 | std::vector vec(10); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch07/ex7_53.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_53.h 3 | // Exercise 7.53 4 | // 5 | // Created by pezy on 11/25/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_53_h 10 | #define CP5_ex7_53_h 11 | 12 | class Debug { 13 | public: 14 | constexpr Debug(bool b = true) : rt(b), io(b), other(b) {} 15 | constexpr Debug(bool r, bool i, bool o) : rt(r), io(i), other(0) {} 16 | constexpr bool any() { return rt || io || other; } 17 | 18 | void set_rt(bool b) { rt = b; } 19 | void set_io(bool b) { io = b; } 20 | void set_other(bool b) { other = b; } 21 | 22 | private: 23 | bool rt; // runtime error 24 | bool io; // I/O error 25 | bool other; // the others 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /ch07/ex7_57.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_57.h 3 | // Exercise 7.57 4 | // 5 | // Created by pezy on 11/25/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_57_h 10 | #define CP5_ex7_57_h 11 | 12 | #include 13 | 14 | class Account { 15 | public: 16 | void calculate() { amount += amount * interestRate; } 17 | static double rate() { return interestRate; } 18 | static void rate(double newRate) { interestRate = newRate; } 19 | 20 | private: 21 | std::string owner; 22 | double amount; 23 | static double interestRate; 24 | static constexpr double todayRate = 42.42; 25 | static double initRate() { return todayRate; } 26 | }; 27 | 28 | double Account::interestRate = initRate(); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /ch08/ex8_02.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex8_02.cpp 3 | // Exercise 8.2 4 | // 5 | // Created by pezy on 11/27/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Test your function by calling it, passing cin as an argument 9 | 10 | #include 11 | using std::istream; 12 | 13 | istream& func(istream& is) 14 | { 15 | std::string buf; 16 | while (is >> buf) std::cout << buf << std::endl; 17 | is.clear(); 18 | return is; 19 | } 20 | 21 | int main() 22 | { 23 | istream& is = func(std::cin); 24 | std::cout << is.rdstate() << std::endl; 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch08/ex8_04.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex8_04.cpp 3 | // Exercise 8.4 4 | // 5 | // Created by pezy on 11/9/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Write a function to open a file for input and read its contents into 9 | // a vector of strings, 10 | // storing each line as a separate element in the vector. 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | using std::vector; 18 | using std::string; 19 | using std::ifstream; 20 | using std::cout; 21 | using std::endl; 22 | 23 | void ReadFileToVec(const string& fileName, vector& vec) 24 | { 25 | ifstream ifs(fileName); 26 | if (ifs) { 27 | string buf; 28 | while (std::getline(ifs, buf)) vec.push_back(buf); 29 | } 30 | } 31 | 32 | int main() 33 | { 34 | vector vec; 35 | ReadFileToVec("../data/book.txt", vec); 36 | for (const auto& str : vec) cout << str << endl; 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /ch08/ex8_05.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex8_05.cpp 3 | // Exercise 8.5 4 | // 5 | // Created by pezy on 11/9/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Rewrite the previous program to store each word in a separate 9 | // element. 10 | // @See ex8_04.cpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | using std::vector; 18 | using std::string; 19 | using std::ifstream; 20 | using std::cout; 21 | using std::endl; 22 | 23 | void ReadFileToVec(const string& fileName, vector& vec) 24 | { 25 | ifstream ifs(fileName); 26 | if (ifs) { 27 | string buf; 28 | while (ifs >> buf) vec.push_back(buf); 29 | } 30 | } 31 | 32 | int main() 33 | { 34 | vector vec; 35 | ReadFileToVec("../data/book.txt", vec); 36 | for (const auto& str : vec) cout << str << endl; 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /ch08/ex8_06.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "../ch07/ex7_26_sales_data.h" 5 | 6 | int main(int argc, char** argv) 7 | { 8 | std::ifstream input(argv[1]); // use "../data/book.txt" 9 | 10 | Sales_data total; 11 | if (read(input, total)) { 12 | Sales_data trans; 13 | while (read(input, trans)) { 14 | if (total.isbn() == trans.isbn()) 15 | total.combine(trans); 16 | else { 17 | print(std::cout, total) << std::endl; 18 | total = trans; 19 | } 20 | } 21 | print(std::cout, total) << std::endl; 22 | } 23 | else { 24 | std::cerr << "No data?!" << std::endl; 25 | } 26 | } 27 | 28 | /* 29 | *! Output: 30 | *! 0-201-78345-X 5 110 31 | *! 0-201-78346-X 9 839.2 32 | */ -------------------------------------------------------------------------------- /ch08/ex8_07.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../ch07/ex7_26_sales_data.h" 4 | 5 | int main(int argc, char** argv) 6 | { 7 | std::ifstream input(argv[1]); // "../data/book.txt" 8 | std::ofstream output(argv[2]); // "../data/out.txt" 9 | 10 | Sales_data total; 11 | if (read(input, total)) { 12 | Sales_data trans; 13 | while (read(input, trans)) { 14 | if (total.isbn() == trans.isbn()) 15 | total.combine(trans); 16 | else { 17 | print(output, total) << std::endl; 18 | total = trans; 19 | } 20 | } 21 | print(output, total) << std::endl; 22 | } 23 | else { 24 | std::cerr << "No data?!" << std::endl; 25 | } 26 | } -------------------------------------------------------------------------------- /ch08/ex8_08.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../ch07/ex7_26_sales_data.h" 4 | 5 | int main(int argc, char** argv) 6 | { 7 | std::ifstream input(argv[1]); // "../data/book.txt" 8 | std::ofstream output(argv[2], std::ofstream::app); // "../data/out.txt" 9 | 10 | Sales_data total; 11 | if (read(input, total)) { 12 | Sales_data trans; 13 | while (read(input, trans)) { 14 | if (total.isbn() == trans.isbn()) 15 | total.combine(trans); 16 | else { 17 | print(output, total) << std::endl; 18 | total = trans; 19 | } 20 | } 21 | print(output, total) << std::endl; 22 | } 23 | else { 24 | std::cerr << "No data?!" << std::endl; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ch08/ex8_09.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex8_09.cpp 3 | // Exercise 8.9 4 | // 5 | // Created by pezy on 11/29/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Use the function you wrote for the first exercise in § 8.1.2 (p.314) 9 | // to print the contents of an istringstream object. 10 | // @See Exercise 8.1 11 | 12 | #include 13 | #include 14 | using std::istream; 15 | 16 | istream& func(istream& is) 17 | { 18 | std::string buf; 19 | while (is >> buf) std::cout << buf << std::endl; 20 | is.clear(); 21 | return is; 22 | } 23 | 24 | int main() 25 | { 26 | std::istringstream iss("hello"); 27 | func(iss); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch08/ex8_10.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex8_10.cpp 3 | // Exercise 8.10 4 | // 5 | // Created by pezy on 11/29/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Write a program to store each line from a file in a vector. 9 | // Now use an istringstream to read each element from the vector a word 10 | // at a time. 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using std::vector; 19 | using std::string; 20 | using std::ifstream; 21 | using std::istringstream; 22 | using std::cout; 23 | using std::endl; 24 | using std::cerr; 25 | 26 | int main() 27 | { 28 | ifstream ifs("../data/book.txt"); 29 | if (!ifs) { 30 | cerr << "No data?" << endl; 31 | return -1; 32 | } 33 | 34 | vector vecLine; 35 | string line; 36 | while (getline(ifs, line)) vecLine.push_back(line); 37 | 38 | for (auto& s : vecLine) { 39 | istringstream iss(s); 40 | string word; 41 | while (iss >> word) cout << word << endl; 42 | } 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /ch09/ex9_13.cpp: -------------------------------------------------------------------------------- 1 | //! @author @shbling @Alan 2 | //! 3 | //! Exercise 9.13: 4 | //! How would you initialize a vector from a list? 5 | //! From a vector? 6 | //! Write code to check your answers. 7 | //! 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using std::list; 14 | using std::vector; 15 | using std::cout; 16 | using std::endl; 17 | 18 | int main() 19 | { 20 | list ilst(5, 4); 21 | vector ivc(5, 5); 22 | 23 | //! from list to vector 24 | vector dvc(ilst.begin(), ilst.end()); 25 | for (auto i : ilst) cout << i; 26 | cout << endl; 27 | for (auto t : dvc) cout << t; 28 | cout << endl; 29 | 30 | //! from vector to vector 31 | vector dvc2(ivc.begin(), ivc.end()); 32 | for (auto i : ivc) cout << i; 33 | cout << endl; 34 | for (auto t : dvc2) cout << t; 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /ch09/ex9_14.cpp: -------------------------------------------------------------------------------- 1 | //! @Alan @pezy 2 | //! 3 | //! Exercise 9.14: 4 | //! Write a program to assign the elements from a list of char* pointers 5 | //! to C-style character strings 6 | //! 7 | //! @Notice C-style character strings should use const char*, otherwise warning. 8 | //! 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | int main() 16 | { 17 | std::list l{"Mooophy", "pezy", "Queeuqueg"}; 18 | std::vector v; 19 | v.assign(l.cbegin(), l.cend()); 20 | 21 | for (const auto& ch : v) std::cout << ch << std::endl; 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch09/ex9_15.cpp: -------------------------------------------------------------------------------- 1 | //! @file Exercise 9.15 2 | //! @author pezy 3 | //! @date 2014-12-02 4 | //! @Brief Write a program to determine whether two vectors are equal. 5 | 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | std::vector vec1{1, 2, 3, 4, 5}; 12 | std::vector vec2{1, 2, 3, 4, 5}; 13 | std::vector vec3{1, 2, 3, 4}; 14 | 15 | std::cout << std::boolalpha << (vec1 == vec2) << std::endl; 16 | std::cout << std::boolalpha << (vec1 == vec3) << std::endl; 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /ch09/ex9_16.cpp: -------------------------------------------------------------------------------- 1 | //! @file Exercise 9.16 2 | //! @author pezy 3 | //! @date 2014-12-02 4 | //! @Brief Repeat the previous program, but compare elements in a list to 5 | //! a vector. 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | int main() 12 | { 13 | std::list list{1, 2, 3, 4, 5}; 14 | std::vector vec1{1, 2, 3, 4, 5}; 15 | std::vector vec2{1, 2, 3, 4}; 16 | 17 | std::cout << std::boolalpha 18 | << (std::vector(list.begin(), list.end()) == vec1) 19 | << std::endl; 20 | std::cout << std::boolalpha 21 | << (std::vector(list.begin(), list.end()) == vec2) 22 | << std::endl; 23 | } 24 | -------------------------------------------------------------------------------- /ch09/ex9_18.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex9_18.cpp 3 | // Exercise 9.18 4 | // 5 | // Created by pezy on 12/3/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Write a program to read a sequence of strings from the standard 9 | // input into 10 | // a deque. Use iterators to write a loop to print the elements in the 11 | // deque. 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | using std::string; 18 | using std::deque; 19 | using std::cout; 20 | using std::cin; 21 | using std::endl; 22 | 23 | int main() 24 | { 25 | deque input; 26 | for (string str; cin >> str; input.push_back(str)) 27 | ; 28 | for (auto iter = input.cbegin(); iter != input.cend(); ++iter) 29 | cout << *iter << endl; 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /ch09/ex9_19.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex9_19.cpp 3 | // Exercise 9.19 4 | // 5 | // Created by pezy on 12/3/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Rewrite the program from the previous exercise to use a list. 9 | // List the changes you needed to make. 10 | // @See ex9_18.cpp 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | using std::string; 17 | using std::list; 18 | using std::cout; 19 | using std::cin; 20 | using std::endl; 21 | 22 | int main() 23 | { 24 | list input; 25 | for (string str; cin >> str; input.push_back(str)) 26 | ; 27 | for (auto iter = input.cbegin(); iter != input.cend(); ++iter) 28 | cout << *iter << endl; 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /ch09/ex9_20.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex9_20.cpp 3 | // Exercise 9.20 4 | // 5 | // Created by pezy on 12/3/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Write a program to copy elements from a list into two deques. 9 | // The even-valued elements should go into one deque and the odd ones 10 | // into the other. 11 | 12 | #include 13 | #include 14 | #include 15 | using std::deque; 16 | using std::list; 17 | using std::cout; 18 | using std::cin; 19 | using std::endl; 20 | 21 | int main() 22 | { 23 | list l{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 24 | deque odd, even; 25 | for (auto i : l) (i & 0x1 ? odd : even).push_back(i); 26 | 27 | for (auto i : odd) cout << i << " "; 28 | cout << endl; 29 | for (auto i : even) cout << i << " "; 30 | cout << endl; 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /ch09/ex9_22.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::vector; 4 | 5 | void insertDoubleValue(vector& iv, int some_val) 6 | { 7 | auto cursor = iv.size() / 2; 8 | auto iter = iv.begin(), mid = iv.begin() + cursor; 9 | while (iter != mid) { 10 | if (*iter == some_val) { 11 | iter = iv.insert(iter, 2 * some_val); 12 | ++iter; 13 | ++cursor; 14 | mid = iv.begin() + cursor; 15 | } 16 | ++iter; 17 | } 18 | } 19 | 20 | void print(const vector& iv) 21 | { 22 | for (auto i : iv) std::cout << i << " "; 23 | std::cout << std::endl; 24 | } 25 | 26 | int main() 27 | { 28 | vector iv = {1, 1, 1, 1, 1, 7, 1, 9}; 29 | insertDoubleValue(iv, 1); 30 | print(iv); 31 | } 32 | -------------------------------------------------------------------------------- /ch09/ex9_24.cpp: -------------------------------------------------------------------------------- 1 | //! @Yue Wang @pezy 2 | //! 3 | //! Exercise 9.24: 4 | //! Write a program that fetches the first element in a vector using at, 5 | //! the subscript operator, front, and begin. Test your program on an empty 6 | //! vector. 7 | //! 8 | #include 9 | #include 10 | 11 | int main() 12 | { 13 | std::vector v; 14 | std::cout << v.at( 15 | 0); // terminating with uncaught exception of type std::out_of_range 16 | std::cout << v[0]; // Segmentation fault: 11 17 | std::cout << v.front(); // Segmentation fault: 11 18 | std::cout << *v.begin(); // Segmentation fault: 11 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ch09/ex9_27.cpp: -------------------------------------------------------------------------------- 1 | //! @file Exercise 9.27 2 | //! @author pezy 3 | //! @date 2014-12-03 4 | //! @Brief Write a program to find and remove the odd-valued elements in a 5 | //! forward_list. 6 | 7 | #include 8 | #include 9 | 10 | using std::forward_list; 11 | using std::cout; 12 | using std::endl; 13 | 14 | int main() 15 | { 16 | forward_list flst = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 17 | for (auto prev = flst.before_begin(), curr = flst.begin(); 18 | curr != flst.end();) 19 | if (*curr & 0x1) 20 | curr = flst.erase_after(prev); 21 | else 22 | prev = curr++; 23 | 24 | for (auto i : flst) cout << i << " "; 25 | cout << endl; 26 | } 27 | -------------------------------------------------------------------------------- /ch09/ex9_31_1.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex9_31.cpp 3 | // Exercise 9.31 4 | // 5 | // Created by pezy on 12/3/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief The program on page 354 to remove even-valued elements and 9 | // duplicate odd ones will not work on a list or forward_list. Why? 10 | // Revise the program so that it works on these types as well. 11 | // @list iter += 2; -> advance(iter, 2); 12 | // 13 | 14 | #include 15 | #include 16 | 17 | using std::list; 18 | using std::cout; 19 | using std::endl; 20 | using std::advance; 21 | 22 | int main() 23 | { 24 | list vi = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 25 | auto iter = vi.begin(); 26 | while (iter != vi.end()) { 27 | if (*iter % 2) { 28 | iter = vi.insert(iter, *iter); 29 | advance(iter, 2); 30 | } 31 | else 32 | iter = vi.erase(iter); 33 | } 34 | 35 | for (auto i : vi) cout << i << " "; 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /ch09/ex9_33.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex9_33.cpp 3 | // Exercise 9.33 4 | // 5 | // Created by pezy on 12/3/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief In the final example in this section what would happen 9 | // if we did not assign the result of insert to begin? 10 | // Write a program that omits this assignment to see if your 11 | // expectation was correct. 12 | // @Answer crash, cause the iterator is invalid after insert. Because 13 | // Iterators, pointers, and references to a 14 | // vector or string are invalid if the container was reallocated. 15 | 16 | #include 17 | #include 18 | 19 | using std::vector; 20 | using std::cout; 21 | using std::endl; 22 | 23 | int main() 24 | { 25 | vector v{1, 2, 3, 4, 5, 6, 7, 8, 9}; 26 | auto begin = v.begin(); 27 | while (begin != v.end()) { 28 | ++begin; 29 | /*begin = */ v.insert(begin, 42); 30 | ++begin; 31 | } 32 | 33 | for (auto i : v) cout << i << " "; 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /ch09/ex9_38.cpp: -------------------------------------------------------------------------------- 1 | //! @Alan 2 | //! 3 | //! Exercise 9.38: 4 | //! Write a program to explore how vectors grow in the library you use. 5 | //! 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | int main() 12 | { 13 | std::vector v; 14 | std::string word; 15 | 16 | while (std::cin >> word) { 17 | v.push_back(word); 18 | std::cout << v.capacity() << "\n"; 19 | } 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch09/ex9_41.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex9_41.cpp 3 | // Exercise 9.41 4 | // 5 | // Created by pezy on 12/4/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Write a program that initializes a string from a vector. 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | using std::vector; 15 | using std::cout; 16 | using std::endl; 17 | using std::string; 18 | 19 | int main() 20 | { 21 | vector vec{'p', 'e', 'z', 'y'}; 22 | string str(vec.begin(), vec.end()); 23 | 24 | cout << str << endl; 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /ch09/ex9_44.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex9_44.cpp 3 | // Exercise 9.44 4 | // 5 | // Created by pezy on 12/4/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Rewrite the previous function using an index and replace. 9 | // @See 9.43 10 | 11 | #include 12 | #include 13 | 14 | using std::cout; 15 | using std::endl; 16 | using std::string; 17 | using std::prev; 18 | 19 | void Replace(string& s, string const& oldVal, string const& newVal) 20 | { 21 | for (string::size_type i = 0; i != s.size(); ++i) 22 | if (s.substr(i, oldVal.size()) == oldVal) { 23 | s.replace(i, oldVal.size(), newVal); 24 | i += newVal.size() - 1; 25 | } 26 | } 27 | 28 | int main() 29 | { 30 | string str{"To drive straight thru is a foolish, tho courageous act."}; 31 | Replace(str, "tho", "though"); 32 | Replace(str, "thru", "through"); 33 | cout << str << endl; 34 | } 35 | -------------------------------------------------------------------------------- /ch09/ex9_45.cpp: -------------------------------------------------------------------------------- 1 | //! @author @TungWah @Alan 2 | //! @date 4 Oct,2014. 3 | //! 4 | //! Exercise 9.45: 5 | //! Write a funtion that takes a string representing a name and two other 6 | //! strings representing a prefix, such as “Mr.” or “Ms.” and a suffix, 7 | //! such as “Jr.” or “III”. Using iterators and the insert and append functions, 8 | //! generate and return a new string with the suffix and prefix added to the 9 | //! given name. 10 | //! 11 | 12 | #include 13 | #include 14 | 15 | //! Exercise 9.45 16 | std::string pre_suffix(const std::string& name, const std::string& pre, 17 | const std::string& su); 18 | 19 | int main() 20 | { 21 | std::string name("alan"); 22 | std::cout << pre_suffix(name, "Mr.", ",Jr.") << std::endl; 23 | 24 | return 0; 25 | } 26 | 27 | inline std::string pre_suffix(const std::string& name, const std::string& pre, 28 | const std::string& su) 29 | { 30 | auto ret = name; 31 | ret.insert(ret.begin(), pre.begin(), pre.end()); 32 | ret.append(su); 33 | 34 | return ret; 35 | } 36 | -------------------------------------------------------------------------------- /ch09/ex9_46.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex9_46.cpp 3 | // Exercise 9.46 4 | // 5 | // Created by pezy on 12/5/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Rewrite the previous exercise using a position and length to manage 9 | // the strings. 10 | // This time use only the insert function. 11 | // @See 9.45 12 | 13 | #include 14 | #include 15 | 16 | std::string pre_suffix(const std::string& name, const std::string& pre, 17 | const std::string& su) 18 | { 19 | std::string ret(name); 20 | ret.insert(0, pre); 21 | ret.insert(ret.size(), su); 22 | 23 | return ret; 24 | } 25 | 26 | int main() 27 | { 28 | std::string name("alan"); 29 | std::cout << pre_suffix(name, "Mr.", ",Jr."); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /ch09/ex9_49.cpp: -------------------------------------------------------------------------------- 1 | //! @file Exercise 9.49 2 | //! @author pezy 3 | //! @date 2014-12-05 4 | //! @Brief A letter has an ascender if, as with d or f, part of the letter 5 | //! extends above the middle of the line. 6 | // A letter has a descender if, as with p or g, part of the letter 7 | // extends below the line. 8 | // Write a program that reads a file containing words and reports the 9 | // longest word that contains 10 | // neither ascenders nor descenders. 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | using std::string; 17 | using std::ifstream; 18 | using std::cout; 19 | using std::endl; 20 | 21 | int main() 22 | { 23 | ifstream ifs("../data/letter.txt"); 24 | if (!ifs) return -1; 25 | string longest_word; 26 | for (string word; ifs >> word;) 27 | if (word.find_first_not_of("aceimnorsuvwxz") == string::npos && 28 | word.size() > longest_word.size()) 29 | longest_word = word; 30 | 31 | cout << longest_word << endl; 32 | } 33 | -------------------------------------------------------------------------------- /ch09/ex9_50.cpp: -------------------------------------------------------------------------------- 1 | //! @Yue Wang 2 | //! 3 | //! Exercise 9.50: 4 | //! Write a program to process a vectors whose elements represent 5 | //! integral values. 6 | //! Produce the sum of all the elements in that vector. 7 | //! Change the program so that it sums of strings that represent floating-point 8 | //! values. 9 | //! 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | int sum_for_int(const std::vector &v) 16 | { 17 | int sum = 0; 18 | for (auto const& s : v) sum += std::stoi(s); 19 | return sum; 20 | } 21 | 22 | float sum_for_float(const std::vector &v) 23 | { 24 | float sum = 0.0; 25 | for (auto const& s : v) sum += std::stof(s); 26 | return sum; 27 | } 28 | 29 | int main() 30 | { 31 | std::vector v = {"1", "2", "3", "4.5"}; 32 | std::cout << sum_for_int(v) << std::endl; 33 | std::cout << sum_for_float(v) << std::endl; 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /ch10/ex10_01_02.cpp: -------------------------------------------------------------------------------- 1 | //! 2 | //! @author Yue Wang 3 | //! @date 01.12.2014 4 | //! 5 | //! Exercise 10.1: 6 | //! The algorithm header defines a function named count that, like find, 7 | //! takes a pair of iterators and a value.count returns a count of how 8 | //! often that value appears. 9 | //! Read a sequence of ints into a vector and print the count of how many 10 | //! elements have a given value. 11 | //! 12 | //! Exercise 10.2: 13 | //! Repeat the previous program, but read values into a list of strings. 14 | //! 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | int main() 23 | { 24 | //! 10.1 25 | std::vector v = {1, 2, 3, 4, 5, 6, 6, 6, 2}; 26 | std::cout << "ex 10.01: " << std::count(v.cbegin(), v.cend(), 6) 27 | << std::endl; 28 | 29 | //! 10.2 30 | std::list l = {"aa", "aaa", "aa", "cc"}; 31 | std::cout << "ex 10.02: " << std::count(l.cbegin(), l.cend(), "aa") 32 | << std::endl; 33 | 34 | return 0; 35 | } 36 | //! output: 37 | //! 38 | // ex 10.01: 3 39 | // ex 10.02: 2 40 | -------------------------------------------------------------------------------- /ch10/ex10_06.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex10_06.cpp 3 | // Exercise 10.6 4 | // 5 | // Created by pezy on 12/9/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Using fill_n, write a program to set a sequence of int values to 0. 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | using std::vector; 15 | using std::cout; 16 | using std::endl; 17 | using std::fill_n; 18 | 19 | int main() 20 | { 21 | vector vec{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 22 | fill_n(vec.begin(), vec.size(), 0); 23 | 24 | for (auto i : vec) cout << i << " "; 25 | cout << endl; 26 | } 27 | 28 | // @Output 29 | // 0 0 0 0 0 0 0 0 0 0 -------------------------------------------------------------------------------- /ch10/ex10_12.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "../ch07/ex7_26_sales_data.h" // Sales_data class. 6 | 7 | bool compareIsbn(const Sales_data& sd1, const Sales_data& sd2) 8 | { 9 | return sd1.isbn() < sd2.isbn(); 10 | } 11 | 12 | int main() 13 | { 14 | Sales_data d1("CppPrimer"), d2("JavaCore"), d3("PythonCookBook"), 15 | d4("CppCore"), d5("AwesomeCPP"); 16 | std::vector v{d1, d2, d3, d4, d5}; 17 | 18 | //! @note the elements the iterators pointing to 19 | //! must match the parameters of the predicate. 20 | std::sort(v.begin(), v.end(), compareIsbn); 21 | 22 | for (const auto& element : v) std::cout << element.isbn() << " "; 23 | std::cout << std::endl; 24 | } 25 | -------------------------------------------------------------------------------- /ch10/ex10_17.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "../ch07/ex7_26_sales_data.h" // Sales_data class. 5 | 6 | int main() 7 | { 8 | Sales_data d1("CppPrimer"), d2("JavaCore"), d3("PythonCookBook"), 9 | d4("CppCore"), d5("AwesomeCPP"); 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() < sd2.isbn(); 15 | }); 16 | 17 | for (const auto& element : v) std::cout << element.isbn() << " "; 18 | std::cout << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /ch10/ex10_20.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | * @question: 3 | * The library defines an algorithm named `count_if`. 4 | * Like `find_if`, this function takes a pair of iterators 5 | * denoting an input range and a predicate that 6 | * it applies to each element in the given range. 7 | * `count_if` returns a count of how often the predicate is true. 8 | * Use `count_if` to rewrite the portion of our program that 9 | * counted how many words are greater than length 6. 10 | * @author: pezy 11 | * @date: 2016-07-01 12 | * @see: [Implicit Captures] - biggies funciton. 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | using std::vector; 21 | using std::string; 22 | using std::cout; 23 | using std::endl; 24 | 25 | int main() 26 | { 27 | vector words{"cppprimer", "pezy", "learncpp", 28 | "greater", "rewrite", "programmer"}; 29 | 30 | cout << std::count_if(words.cbegin(), words.cend(), [](const string& word) { 31 | return word.size() > 6; 32 | }) << std::endl; 33 | } 34 | -------------------------------------------------------------------------------- /ch10/ex10_21.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | * @question: 3 | * Write a lambda that captures a local `int` variable and 4 | * decrements that variable until it reaches 0. 5 | * Once the variable is 0 additional calls should 6 | * no longer decrement the variable. 7 | * The lambda should return a `bool` that indicates 8 | * whether the captured variable is 0. 9 | * @author: pezy 10 | * @date: 2016-07-01 11 | * @see: 12 | */ 13 | 14 | #include 15 | 16 | using std::cout; 17 | using std::endl; 18 | 19 | int main() 20 | { 21 | // local int variable 22 | int local_val = 7; 23 | auto decrement_to_zero = [&local_val]() { 24 | if (local_val == 0) 25 | return true; 26 | else { 27 | --local_val; 28 | return false; 29 | } 30 | }; 31 | 32 | while (!decrement_to_zero()) cout << local_val << endl; 33 | } 34 | -------------------------------------------------------------------------------- /ch10/ex10_22.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex10_22.cpp 3 | // Exercise 10.22 4 | // 5 | // Created by pezy on 12/11/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Rewrite the program to count words of size 6 or less using 9 | // functions in place of the lambdas. 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | using std::string; 19 | using namespace std::placeholders; 20 | 21 | bool lessThanOrEqualTo(const string& s, string::size_type sz) 22 | { 23 | return s.size() <= sz; 24 | } 25 | 26 | int main() 27 | { 28 | std::vector authors{"Mooophy", "pezy", "Queequeg90", "shbling", 29 | "evan617"}; 30 | std::cout << count_if(authors.cbegin(), authors.cend(), 31 | bind(lessThanOrEqualTo, _1, 6)); 32 | } 33 | 34 | // @Out 35 | // 1 -------------------------------------------------------------------------------- /ch10/ex10_27.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex10_27.cpp 3 | // Exercise 10.27 4 | // 5 | // Created by pezy on 12/13/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // In addition to unique, the library defines function named unique_copy that 9 | // takes a third iterator denoting a destination into which to copy the unique 10 | // elements. 11 | // Write a program that uses unique_copy to copy the unique elements from 12 | // a vector into an initially empty list. 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | int main() 20 | { 21 | std::vector vec{3, 5, 1, 5, 1, 7, 3, 7, 9}; 22 | std::list lst; 23 | 24 | std::sort(vec.begin(), vec.end()); 25 | std::unique_copy(vec.begin(), vec.end(), back_inserter(lst)); 26 | for (auto i : lst) std::cout << i << " "; 27 | std::cout << std::endl; 28 | } 29 | -------------------------------------------------------------------------------- /ch10/ex10_29.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex10_29.cpp 3 | // Exercise 10.29 4 | // 5 | // Created by pezy on 12/13/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Write a program using stream iterators to read a text file into a vector of 9 | // strings. 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | using std::string; 18 | 19 | int main() 20 | { 21 | std::ifstream ifs("../data/book.txt"); 22 | std::istream_iterator in(ifs), eof; 23 | std::vector vec; 24 | std::copy(in, eof, back_inserter(vec)); 25 | 26 | // output 27 | std::copy(vec.cbegin(), vec.cend(), 28 | std::ostream_iterator(std::cout, "\n")); 29 | } 30 | -------------------------------------------------------------------------------- /ch10/ex10_30.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex10_30.cpp 3 | // Exercise 10.30 4 | // 5 | // Created by pezy on 12/13/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Use stream iterators, sort, and copy to read a sequence of integers from the 9 | // standard input, 10 | // sort them, and then write them back to the standard output. 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | int main() 18 | { 19 | std::istream_iterator in_iter(std::cin), eof; 20 | std::vector vec; 21 | while (in_iter != eof) vec.push_back(*in_iter++); 22 | std::sort(vec.begin(), vec.end()); 23 | std::copy(vec.cbegin(), vec.cend(), 24 | std::ostream_iterator(std::cout, " ")); 25 | } -------------------------------------------------------------------------------- /ch10/ex10_31.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex10_31.cpp 3 | // Exercise 10.31 4 | // 5 | // Created by pezy on 12/13/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Update the program from the previous exercise so that it prints only the 9 | // unique elements. 10 | // Your program should use unqiue_copy 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | int main() 18 | { 19 | std::istream_iterator in_iter(std::cin), eof; 20 | std::vector vec; 21 | while (in_iter != eof) vec.push_back(*in_iter++); 22 | std::sort(vec.begin(), vec.end()); 23 | std::unique_copy(vec.cbegin(), vec.cend(), 24 | std::ostream_iterator(std::cout, " ")); 25 | } -------------------------------------------------------------------------------- /ch10/ex10_42.cpp: -------------------------------------------------------------------------------- 1 | //! @Alan @pezy 2 | //! 3 | //! Exercise 10.42: 4 | //! Reimplement the program that eliminated duplicate words that 5 | //! we wrote in § 10.2.3 (p. 383) to use a list instead of a vector. 6 | //! 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using std::string; 13 | using std::list; 14 | 15 | void elimDups(list& words) 16 | { 17 | words.sort(); 18 | words.unique(); 19 | } 20 | 21 | int main() 22 | { 23 | list l = {"aa", "aa", "aa", "aa", "aasss", "aa"}; 24 | elimDups(l); 25 | for (const auto& e : l) std::cout << e << " "; 26 | std::cout << std::endl; 27 | } 28 | 29 | //! output 30 | //! 31 | // aa aasss 32 | -------------------------------------------------------------------------------- /ch11/ex11_11.cpp: -------------------------------------------------------------------------------- 1 | #include "../ch07/ex7_26_sales_data.h" 2 | #include 3 | 4 | bool compareIsbn(const Sales_data& lhs, const Sales_data& rhs) 5 | { 6 | return lhs.isbn() < rhs.isbn(); 7 | } 8 | 9 | int main() 10 | { 11 | using compareType = bool (*)(const Sales_data& lhs, const Sales_data& rhs); 12 | // typedef bool(*compareType)(const Sales_data &lhs, const Sales_data &rhs); 13 | std::multiset bookstore(compareIsbn); 14 | } -------------------------------------------------------------------------------- /ch11/ex11_12_13.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex11_12_13.cpp 3 | // Exercise 11.12 11.13 4 | // 5 | // Created by pezy on 12/15/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Write a program to read a sequence of strings and ints, 9 | // storing each into a pair. Store the pairs in a vector. 10 | // 11 | // There are at least three ways to create the pairs in the program for the 12 | // previous exercise. 13 | // Write three versions of that program, creating the pairs in each way. 14 | // Explain which form you think is easiest to write and understand, and why. 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | int main() 22 | { 23 | std::vector> vec; 24 | std::string str; 25 | int i; 26 | while (std::cin >> str >> i) 27 | vec.push_back(std::pair(str, i)); 28 | // vec.push_back(std::make_pair(str, i)); 29 | // vec.push_back({str, i}); 30 | // vec.emplace_back(str, i); //!!! easiest way. 31 | 32 | for (const auto& p : vec) 33 | std::cout << p.first << ":" << p.second << std::endl; 34 | } -------------------------------------------------------------------------------- /ch11/ex11_18.cpp: -------------------------------------------------------------------------------- 1 | //! @Alan 2 | //! 3 | //! Exercise 11.18: 4 | //! Write the type of map_it from the loop on page 430 without using auto or 5 | //! decltype. 6 | //! 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | int main() 13 | { 14 | std::map word_count; 15 | 16 | //! the orignal codes: 17 | // auto map_it = word_count.cbegin(); 18 | 19 | std::map::const_iterator map_it = word_count.cbegin(); 20 | //! ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 21 | //! the type ex11.18 required. 22 | 23 | // compare the current iterator to the off-the-end iterator 24 | while (map_it != word_count.cend()) { 25 | // dereference the iterator to print the element key--value pairs 26 | std::cout << map_it->first << " occurs " << map_it->second << " times" 27 | << std::endl; 28 | ++map_it; // increment the iterator to denote the next element 29 | } 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /ch11/ex11_20.cpp: -------------------------------------------------------------------------------- 1 | //! @Alan @pezy 2 | //! 3 | //! Exercise 11.20: 4 | //! Rewrite the word-counting program from § 11.1 (p. 421) to use insert instead 5 | //! of subscripting. Which program do you think is easier to write and read? 6 | //! Explain your reasoning. 7 | //! 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using std::string; 14 | 15 | int main() 16 | { 17 | std::map word_count; 18 | string word; 19 | while (std::cin >> word) { 20 | auto ret = word_count.insert({word, 1}); 21 | if (!ret.second) ++ret.first->second; 22 | } 23 | 24 | //! print the content of the map. 25 | for (const auto& w : word_count) 26 | std::cout << w.first << " " << w.second 27 | << ((w.second > 1) ? " times" : " time") << std::endl; 28 | } 29 | -------------------------------------------------------------------------------- /ch11/ex11_23.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex11_23.cpp 3 | // Exercise 11.23 4 | // 5 | // Created by pezy on 12/16/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Rewrite the map that stored vectors of children’s names with a key that is 9 | // the family last name for the exercises in 11.2.1 (p. 424) to use a multimap. 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | using std::string; 16 | 17 | int main() 18 | { 19 | std::multimap families; 20 | for (string lastName, childName; std::cin >> childName >> lastName; 21 | families.emplace(lastName, childName)) 22 | ; 23 | for (const auto& s : families) 24 | std::cout << s.second << " " << s.first << std::endl; 25 | } -------------------------------------------------------------------------------- /ch11/ex11_32.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex11_32.cpp 3 | // Exercise 11.32 4 | // 5 | // Created by pezy on 12/17/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Using the multimap from the previous exercise, write a program to print the 9 | // list of **authors and their works** alphabetically. 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using std::string; 17 | 18 | int main() 19 | { 20 | std::multimap authors{ 21 | {"alan", "DMA"}, {"pezy", "LeetCode"}, {"alan", "CLRS"}, 22 | {"wang", "FTP"}, {"pezy", "CP5"}, {"wang", "CPP-Concurrency"}}; 23 | std::map> order_authors; 24 | for (const auto& author : authors) 25 | order_authors[author.first].insert(author.second); 26 | for (const auto& author : order_authors) { 27 | std::cout << author.first << ": "; 28 | for (const auto& work : author.second) std::cout << work << " "; 29 | std::cout << std::endl; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ch12/ex12_02_TEST.cpp: -------------------------------------------------------------------------------- 1 | #include "ex12_02.h" 2 | #include 3 | 4 | int main() 5 | { 6 | const StrBlob csb{"hello", "world", "pezy"}; 7 | StrBlob sb{"hello", "world", "Mooophy"}; 8 | 9 | std::cout << csb.front() << " " << csb.back() << std::endl; 10 | sb.back() = "pezy"; 11 | std::cout << sb.front() << " " << sb.back() << std::endl; 12 | } 13 | -------------------------------------------------------------------------------- /ch12/ex12_13.cpp: -------------------------------------------------------------------------------- 1 | //! @Yue Wang 2 | //! 3 | //! ex12.13 What happens if we excute the following code? 4 | //! 5 | // generate a runtime error : double free 6 | //! 7 | 8 | #include 9 | #include 10 | 11 | int main() 12 | { 13 | { 14 | auto sp = std::make_shared(); 15 | auto p = sp.get(); 16 | delete p; 17 | } 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ch12/ex12_16.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex12_15.cpp 3 | // Exercise 12.15 4 | // 5 | // Created by pezy on 12/22/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Compilers don’t always give easy-to-understand error messages if we attempt 9 | // to 10 | // copy or assign a unique_ptr. Write a program that contains these errors to 11 | // see 12 | // how your compiler diagnoses them. 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | using std::string; 19 | using std::unique_ptr; 20 | 21 | int main() 22 | { 23 | unique_ptr p1(new string("pezy")); 24 | // unique_ptr p2(p1); // copy 25 | // ^ 26 | // Error: Call to implicitly-deleted copy constructor of 27 | // 'unique_ptr' 28 | // 29 | // unique_ptr p3 = p1; // assign 30 | // ^ 31 | // Error: Call to implicitly-deleted copy constructor of 32 | // 'unique_ptr' 33 | std::cout << *p1 << std::endl; 34 | p1.reset(nullptr); 35 | } -------------------------------------------------------------------------------- /ch12/ex12_19.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex12_19.cpp 3 | // Exercise 12.19 4 | // 5 | // Created by pezy on 12/26/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Define your own version of StrBlobPtr and 9 | // update your StrBlob class with the appropriate friend declaration and begin 10 | // and end members. 11 | // 12 | // @See ex12_19.h 13 | 14 | #include "ex12_19.h" 15 | 16 | StrBlobPtr StrBlob::begin() 17 | { 18 | return StrBlobPtr(*this); 19 | } 20 | StrBlobPtr StrBlob::end() 21 | { 22 | return StrBlobPtr(*this, data->size()); 23 | } 24 | -------------------------------------------------------------------------------- /ch12/ex12_20.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex12_20.cpp 3 | // Exercise 12.20 4 | // 5 | // Created by pezy on 12/26/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Write a program that reads an input file a line at a time into 9 | // a StrBlob and uses a StrBlobPtr to print each element in that StrBlob. 10 | 11 | #include "ex12_19.h" 12 | #include 13 | #include 14 | 15 | int main() 16 | { 17 | std::ifstream ifs("../data/book.txt"); 18 | StrBlob blob; 19 | for (std::string str; std::getline(ifs, str);) blob.push_back(str); 20 | for (StrBlobPtr pbeg(blob.begin()), pend(blob.end()); pbeg != pend; 21 | pbeg.incr()) 22 | std::cout << pbeg.deref() << std::endl; 23 | } -------------------------------------------------------------------------------- /ch12/ex12_22.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex12_22.cpp 3 | // CP5 4 | // 5 | // Created by pezy on 1/2/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | 9 | #include "ex12_22.h" 10 | 11 | ConstStrBlobPtr StrBlob::begin() const // should add const 12 | { 13 | return ConstStrBlobPtr(*this); 14 | } 15 | ConstStrBlobPtr StrBlob::end() const // should add const 16 | { 17 | return ConstStrBlobPtr(*this, data->size()); 18 | } -------------------------------------------------------------------------------- /ch12/ex12_23.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex12_23.cpp 3 | // Exercise 12.23 4 | // 5 | // Created by pezy on 12/30/14. 6 | // Updated by sanerror on 11/9/16. 7 | // Copyright (c) 2014 pezy. All rights reserved. 8 | // 9 | // Write a program to concatenate two string literals, putting the result in a 10 | // dynamically allocated array of char. 11 | // Write a program to concatenate two library strings that have the same value 12 | // as the literals used in the first program. 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | int main() { 19 | const char *c1 = "Hello "; 20 | const char *c2 = "World"; 21 | unsigned len = strlen(c1) + strlen(c2) + 1; 22 | char *r = new char[len](); 23 | strcat_s(r, len, c1); 24 | strcat_s(r, len, c2); 25 | std::cout << r << std::endl; 26 | 27 | std::string s1 = "Hello "; 28 | std::string s2 = "World"; 29 | strcpy_s(r, len, (s1 + s2).c_str()); 30 | std::cout << r << std::endl; 31 | 32 | delete[] r; 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /ch12/ex12_24.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex12_24.cpp 3 | // Exercise 12.24 4 | // 5 | // Created by pezy on 12/30/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Write a program that reads a string from the standard input into a 9 | // dynamically allocated character array. 10 | // Describe how your program handles varying size inputs. 11 | // Test your program by giving it a string of data that is longer than the 12 | // array size you've allocated. 13 | 14 | #include 15 | 16 | int main() 17 | { 18 | // need to tell the size. 19 | std::cout << "How long do you want the string? "; 20 | int size{0}; 21 | std::cin >> size; 22 | char* input = new char[size + 1](); 23 | std::cin.ignore(); 24 | std::cout << "input the string: "; 25 | std::cin.get(input, size + 1); 26 | std::cout << input; 27 | delete[] input; 28 | // Test: if longer than the array size, we will lost the characters which 29 | // are out of range. 30 | } 31 | -------------------------------------------------------------------------------- /ch12/ex12_26.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex12_26.cpp 3 | // Exercise 12.26 4 | // 5 | // Created by pezy on 12/30/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Rewrite the program on page 481 using an allocator. 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | void input_reverse_output_string(int n) 15 | { 16 | std::allocator alloc; 17 | auto const p = alloc.allocate(n); 18 | std::string s; 19 | auto q = p; 20 | while (std::cin >> s && q != p + n) alloc.construct(q++, s); 21 | 22 | while (q != p) { 23 | std::cout << *--q << " "; 24 | alloc.destroy(q); 25 | } 26 | alloc.deallocate(p, n); 27 | } 28 | 29 | int main() 30 | { 31 | input_reverse_output_string(5); 32 | } 33 | -------------------------------------------------------------------------------- /ch12/ex12_27_30_TEST.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex12_27_TEST.cpp 3 | // Exercise 12.27 4 | // 5 | // Created by pezy on 12/31/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // The TextQuery and QueryResult classes use only capabilities that we have 9 | // already covered. 10 | // Without looking ahead, write your own versions of these classes. 11 | 12 | #include "ex12_27_30.h" 13 | #include 14 | 15 | void runQueries(std::ifstream& infile) 16 | { 17 | TextQuery tq(infile); 18 | while (true) { 19 | std::cout << "enter word to look for, or q to quit: "; 20 | string s; 21 | if (!(std::cin >> s) || s == "q") break; 22 | print(std::cout, tq.query(s)) << std::endl; 23 | } 24 | } 25 | 26 | int main() 27 | { 28 | std::ifstream file("../data/storyDataFile.txt"); 29 | runQueries(file); 30 | } 31 | -------------------------------------------------------------------------------- /ch13/ex13_05.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_05.h 3 | // CP5 4 | // 5 | // Created by pezy on 1/5/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Given the following sketch of a class, write a copy constructor that copies 9 | // all the members. 10 | // Your constructor should dynamically allocate a new string and copy the 11 | // object to which ps points, 12 | // rather than copying ps itself. 13 | 14 | #ifndef CP5_ex13_05_h 15 | #define CP5_ex13_05_h 16 | 17 | #include 18 | 19 | class HasPtr { 20 | public: 21 | HasPtr(const std::string& s = std::string()) : ps(new std::string(s)), i(0) 22 | { 23 | } 24 | HasPtr(const HasPtr& hp) : ps(new std::string(*hp.ps)), i(hp.i) {} 25 | private: 26 | std::string* ps; 27 | int i; 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /ch13/ex13_08.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_08.h 3 | // CP5 4 | // 5 | // Created by pezy on 1/12/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Write the assignment operator for the HasPtr class from exercise 13.5 in 9 | // 13.1.1 (p. 499). 10 | // As with the copy constructor, your assignment operator should copy the 11 | // object to which ps points. 12 | // 13 | // See ex13_05.h 14 | 15 | #ifndef CP5_ex13_08_h 16 | #define CP5_ex13_08_h 17 | 18 | #include 19 | 20 | class HasPtr { 21 | public: 22 | HasPtr(const std::string& s = std::string()) : ps(new std::string(s)), i(0) 23 | { 24 | } 25 | HasPtr(const HasPtr& hp) : ps(new std::string(*hp.ps)), i(hp.i) {} 26 | HasPtr& operator=(const HasPtr& hp) 27 | { 28 | std::string* new_ps = new std::string(*hp.ps); 29 | delete ps; 30 | ps = new_ps; 31 | i = hp.i; 32 | return *this; 33 | } 34 | 35 | private: 36 | std::string* ps; 37 | int i; 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /ch13/ex13_11.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_11.h 3 | // CP5 4 | // 5 | // Created by pezy on 1/13/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Add a destructor to your HasPtr class from the previous exercises. 9 | // 10 | // See ex13_08.h 11 | 12 | #ifndef CP5_ex13_11_h 13 | #define CP5_ex13_11_h 14 | 15 | #include 16 | 17 | class HasPtr { 18 | public: 19 | HasPtr(const std::string& s = std::string()) : ps(new std::string(s)), i(0) 20 | { 21 | } 22 | HasPtr(const HasPtr& hp) : ps(new std::string(*hp.ps)), i(hp.i) {} 23 | HasPtr& operator=(const HasPtr& hp) 24 | { 25 | std::string* new_ps = new std::string(*hp.ps); 26 | delete ps; 27 | ps = new_ps; 28 | i = hp.i; 29 | return *this; 30 | } 31 | ~HasPtr() { delete ps; } 32 | private: 33 | std::string* ps; 34 | int i; 35 | }; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /ch13/ex13_17_1.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_17.cpp 3 | // Exercise 13.17 4 | // 5 | // Created by pezy on 1/15/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Write versions of numbered and f corresponding to the previous three 9 | // exercises 10 | // and check whether you correctly predicted the output. 11 | // 12 | // For 13.14 13 | 14 | #include 15 | 16 | class numbered { 17 | public: 18 | numbered() 19 | { 20 | static int unique = 10; 21 | mysn = unique++; 22 | } 23 | 24 | int mysn; 25 | }; 26 | 27 | void f(numbered s) 28 | { 29 | std::cout << s.mysn << std::endl; 30 | } 31 | 32 | int main() 33 | { 34 | numbered a, b = a, c = b; 35 | f(a); 36 | f(b); 37 | f(c); 38 | } 39 | 40 | // output 41 | // 10 42 | // 10 43 | // 10 44 | -------------------------------------------------------------------------------- /ch13/ex13_17_2.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_17.cpp 3 | // Exercise 13.17 4 | // 5 | // Created by pezy on 1/15/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Write versions of numbered and f corresponding to the previous three 9 | // exercises 10 | // and check whether you correctly predicted the output. 11 | // 12 | // For 13.15 13 | 14 | #include 15 | 16 | class numbered { 17 | public: 18 | numbered() 19 | { 20 | static int unique = 10; 21 | mysn = unique++; 22 | } 23 | 24 | numbered(const numbered& n) { mysn = n.mysn + 1; } 25 | 26 | int mysn; 27 | }; 28 | 29 | void f(numbered s) 30 | { 31 | std::cout << s.mysn << std::endl; 32 | } 33 | 34 | int main() 35 | { 36 | numbered a, b = a, c = b; 37 | f(a); 38 | f(b); 39 | f(c); 40 | } 41 | 42 | // output 43 | // 11 44 | // 12 45 | // 13 46 | -------------------------------------------------------------------------------- /ch13/ex13_17_3.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_17.cpp 3 | // Exercise 13.17 4 | // 5 | // Created by pezy on 1/15/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Write versions of numbered and f corresponding to the previous three 9 | // exercises 10 | // and check whether you correctly predicted the output. 11 | // 12 | // For 13.16 13 | 14 | #include 15 | 16 | class numbered { 17 | public: 18 | numbered() 19 | { 20 | static int unique = 10; 21 | mysn = unique++; 22 | } 23 | 24 | numbered(const numbered& n) { mysn = n.mysn + 1; } 25 | 26 | int mysn; 27 | }; 28 | 29 | void f(const numbered& s) 30 | { 31 | std::cout << s.mysn << std::endl; 32 | } 33 | 34 | int main() 35 | { 36 | numbered a, b = a, c = b; 37 | f(a); 38 | f(b); 39 | f(c); 40 | } 41 | 42 | // output 43 | // 10 44 | // 11 45 | // 12 46 | -------------------------------------------------------------------------------- /ch13/ex13_18.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_18.cpp 3 | // Exercise 13.18 4 | // 5 | // Created by pezy on 1/15/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Define an Employee class that contains an employee name and a unique 9 | // employee identifier. 10 | // Give the class a default constructor and a constructor that 11 | // takes a string representing the employee’s name. 12 | // Each constructor should generate a unique ID by incrementing a static data 13 | // member. 14 | // 15 | 16 | #include "ex13_18.h" 17 | 18 | int Employee::s_increment = 0; 19 | 20 | Employee::Employee() 21 | { 22 | id_ = s_increment++; 23 | } 24 | 25 | Employee::Employee(const string& name) 26 | { 27 | id_ = s_increment++; 28 | name_ = name; 29 | } -------------------------------------------------------------------------------- /ch13/ex13_18.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_18.h 3 | // Exercise 13.18 4 | // 5 | // Created by pezy on 1/15/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Define an Employee class that contains an employee name and a unique 9 | // employee identifier. 10 | // Give the class a default constructor and a constructor that 11 | // takes a string representing the employee’s name. 12 | // Each constructor should generate a unique ID by incrementing a static data 13 | // member. 14 | // 15 | 16 | #ifndef CP5_ex13_18_h 17 | #define CP5_ex13_18_h 18 | 19 | #include 20 | using std::string; 21 | 22 | class Employee { 23 | public: 24 | Employee(); 25 | Employee(const string& name); 26 | 27 | const int id() const { return id_; } 28 | 29 | private: 30 | string name_; 31 | int id_; 32 | static int s_increment; 33 | }; 34 | 35 | #endif -------------------------------------------------------------------------------- /ch13/ex13_19.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_19.h 3 | // Exercise 13.19 4 | // 5 | // Created by pezy on 1/15/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Does your Employee class need to define its own versions of the copy-control 9 | // members? 10 | // If so, why? If not, why not? 11 | // Implement whatever copy-control members you think Employee needs. 12 | // 13 | // Answer: No, cause there really is no sensible meaning. employee can't copy 14 | // in real world. 15 | 16 | #ifndef CP5_ex13_19_h 17 | #define CP5_ex13_19_h 18 | 19 | #include 20 | using std::string; 21 | 22 | class Employee { 23 | public: 24 | Employee(); 25 | Employee(const string& name); 26 | Employee(const Employee&) = delete; 27 | Employee& operator=(const Employee&) = delete; 28 | 29 | const int id() const { return id_; } 30 | 31 | private: 32 | string name_; 33 | int id_; 34 | static int s_increment; 35 | }; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /ch13/ex13_22.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pezy/CppPrimer/9aaadff38cd6d1d74231bc59d185090efea49798/ch13/ex13_22.h -------------------------------------------------------------------------------- /ch13/ex13_26.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_26.cpp 3 | // Exercise 13.26 4 | // 5 | // Created by pezy on 1/19/15. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Write your own version of the StrBlob class described in the previous 9 | // exercise. 10 | // 11 | // @See ex12_22 and ex13_25 12 | 13 | #include "ex13_26.h" 14 | 15 | ConstStrBlobPtr StrBlob::begin() const // should add const 16 | { 17 | return ConstStrBlobPtr(*this); 18 | } 19 | ConstStrBlobPtr StrBlob::end() const // should add const 20 | { 21 | return ConstStrBlobPtr(*this, data->size()); 22 | } 23 | 24 | StrBlob& StrBlob::operator=(const StrBlob& sb) 25 | { 26 | data = std::make_shared>(*sb.data); 27 | return *this; 28 | } 29 | -------------------------------------------------------------------------------- /ch13/ex13_27.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_27.h 3 | // Exercise 13.27 4 | // 5 | // Created by pezy on 1/20/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Define your own reference-counted version of HasPtr. 9 | 10 | #ifndef CP5_ex13_27_h 11 | #define CP5_ex13_27_h 12 | 13 | #include 14 | 15 | class HasPtr { 16 | public: 17 | HasPtr(const std::string& s = std::string()) 18 | : ps(new std::string(s)), i(0), use(new size_t(1)) 19 | { 20 | } 21 | HasPtr(const HasPtr& hp) : ps(hp.ps), i(hp.i), use(hp.use) { ++*use; } 22 | HasPtr& operator=(const HasPtr& rhs) 23 | { 24 | ++*rhs.use; 25 | if (--*use == 0) { 26 | delete ps; 27 | delete use; 28 | } 29 | ps = rhs.ps; 30 | i = rhs.i; 31 | use = rhs.use; 32 | return *this; 33 | } 34 | ~HasPtr() 35 | { 36 | if (--*use == 0) { 37 | delete ps; 38 | delete use; 39 | } 40 | } 41 | 42 | private: 43 | std::string* ps; 44 | int i; 45 | size_t* use; 46 | }; 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /ch13/ex13_28.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_28.cpp 3 | // Exercise 13.28 4 | // 5 | // Created by pezy on 1/20/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Given the following classes, implement a default constructor and the 9 | // necessary copy-control members. 10 | 11 | #include "ex13_28.h" 12 | 13 | TreeNode& TreeNode::operator=(const TreeNode& rhs) 14 | { 15 | ++*rhs.count; 16 | if (--*count == 0) { 17 | if (left) { 18 | delete left; 19 | left = nullptr; 20 | } 21 | if (right) { 22 | delete right; 23 | right = nullptr; 24 | } 25 | 26 | delete count; 27 | count = nullptr; 28 | } 29 | value = rhs.value; 30 | left = rhs.left; 31 | right = rhs.right; 32 | count = rhs.count; 33 | return *this; 34 | } 35 | 36 | BinStrTree& BinStrTree::operator=(const BinStrTree& bst) 37 | { 38 | TreeNode* new_root = new TreeNode(*bst.root); 39 | delete root; 40 | root = new_root; 41 | return *this; 42 | } 43 | -------------------------------------------------------------------------------- /ch13/ex13_34_36_37_TEST.cpp: -------------------------------------------------------------------------------- 1 | // Unit Test for exercise 13_34_36_37. 2 | 3 | #include "ex13_34_36_37.h" 4 | 5 | int main() 6 | { 7 | Message firstMail("hello"); 8 | Message signInMail("welcome to cppprimer"); 9 | Folder mailBox; 10 | 11 | firstMail.print_debug(); // print: "hello" 12 | firstMail.save(mailBox); // send to mailBox 13 | mailBox.print_debug(); // print: "hello" 14 | 15 | signInMail.print_debug(); // print "welcome to cppprimer" 16 | signInMail.save(mailBox); // send to mailBox 17 | mailBox.print_debug(); // print "welcome to cppprimer hello" 18 | 19 | firstMail = firstMail; // test for assignment to self. 20 | firstMail.print_debug(); // print "hello" 21 | mailBox.print_debug(); // print "welcome to cppprimer hello" 22 | } 23 | -------------------------------------------------------------------------------- /ch13/ex13_42.cpp: -------------------------------------------------------------------------------- 1 | #include "ex13_42_TextQuery.h" 2 | #include 3 | 4 | void runQueries(std::ifstream& infile) 5 | { 6 | TextQuery tq(infile); 7 | while (true) { 8 | std::cout << "enter word to look for, or q to quit: "; 9 | std::string s; 10 | if (!(std::cin >> s) || s == "q") break; 11 | print(std::cout, tq.query(s)) << std::endl; 12 | } 13 | } 14 | 15 | int main() 16 | { 17 | std::ifstream file("../data/storyDataFile.txt"); 18 | runQueries(file); 19 | } 20 | -------------------------------------------------------------------------------- /ch13/ex13_42_TextQuery.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_TEXTQUERY_H_ 2 | #define CP5_TEXTQUERY_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "ex13_42_StrVec.h" 12 | 13 | class QueryResult; 14 | class TextQuery { 15 | public: 16 | TextQuery(std::ifstream&); 17 | QueryResult query(const std::string&) const; 18 | 19 | private: 20 | std::shared_ptr input; 21 | std::map>> result; 22 | }; 23 | 24 | class QueryResult { 25 | public: 26 | friend std::ostream& print(std::ostream&, const QueryResult&); 27 | 28 | public: 29 | QueryResult(const std::string& s, std::shared_ptr> set, 30 | std::shared_ptr v) 31 | : word(s), nos(set), input(v) 32 | { 33 | } 34 | 35 | private: 36 | std::string word; 37 | std::shared_ptr> nos; 38 | std::shared_ptr input; 39 | }; 40 | 41 | std::ostream& print(std::ostream&, const QueryResult&); 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /ch13/ex13_44_47.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_STRING_H__ 2 | #define CP5_STRING_H__ 3 | 4 | #include 5 | 6 | class String { 7 | public: 8 | String() : String("") {} 9 | String(const char*); 10 | String(const String&); 11 | String& operator=(const String&); 12 | ~String(); 13 | 14 | const char* c_str() const { return elements; } 15 | size_t size() const { return end - elements; } 16 | size_t length() const { return end - elements - 1; } 17 | 18 | private: 19 | std::pair alloc_n_copy(const char*, const char*); 20 | void range_initializer(const char*, const char*); 21 | void free(); 22 | 23 | private: 24 | char* elements; 25 | char* end; 26 | std::allocator alloc; 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /ch13/ex13_48.cpp: -------------------------------------------------------------------------------- 1 | #include "ex13_44_47.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 | std::cout << s.c_str() << std::endl; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ch13/ex13_49_Message_TEST.cpp: -------------------------------------------------------------------------------- 1 | // Unit Test for exercise 13_49_Message. 2 | 3 | #include "ex13_49_Message.h" 4 | 5 | int main() 6 | { 7 | Message firstMail("hello"); 8 | Message signInMail("welcome to cppprimer"); 9 | Folder mailBox; 10 | 11 | firstMail.save(mailBox); 12 | signInMail.save(mailBox); 13 | mailBox.print_debug(); 14 | 15 | firstMail = std::move(signInMail); 16 | mailBox.print_debug(); 17 | } 18 | -------------------------------------------------------------------------------- /ch13/ex13_49_String.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_STRING_H__ 2 | #define CP5_STRING_H__ 3 | 4 | #include 5 | 6 | #ifndef _MSC_VER 7 | #define NOEXCEPT noexcept 8 | #else 9 | #define NOEXCEPT 10 | #endif 11 | 12 | class String { 13 | public: 14 | String() : String("") {} 15 | String(const char*); 16 | String(const String&); 17 | String& operator=(const String&); 18 | String(String&&) NOEXCEPT; 19 | String& operator=(String&&) NOEXCEPT; 20 | ~String(); 21 | 22 | const char* c_str() const { return elements; } 23 | size_t size() const { return end - elements; } 24 | size_t length() const { return end - elements - 1; } 25 | 26 | private: 27 | std::pair alloc_n_copy(const char*, const char*); 28 | void range_initializer(const char*, const char*); 29 | void free(); 30 | 31 | private: 32 | char* elements; 33 | char* end; 34 | std::allocator alloc; 35 | }; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /ch13/ex13_53.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex13_53_h 2 | #define CP5_ex13_53_h 3 | 4 | #include 5 | 6 | class HasPtr { 7 | public: 8 | friend void swap(HasPtr&, HasPtr&); 9 | HasPtr(const std::string& s = std::string()); 10 | HasPtr(const HasPtr& hp); 11 | HasPtr(HasPtr&& p) noexcept; 12 | HasPtr& operator=(HasPtr rhs); 13 | // HasPtr& operator=(const HasPtr &rhs); 14 | // HasPtr& operator=(HasPtr &&rhs) noexcept; 15 | ~HasPtr(); 16 | 17 | private: 18 | std::string* ps; 19 | int i; 20 | }; 21 | 22 | #endif // CP5_ex13_53_h 23 | -------------------------------------------------------------------------------- /ch13/ex13_53_test.cpp: -------------------------------------------------------------------------------- 1 | #include "ex13_53.h" 2 | 3 | int main() 4 | { 5 | HasPtr hp1("hello"), hp2("World"), *pH = new HasPtr("World"); 6 | hp1 = hp2; 7 | hp1 = std::move(*pH); 8 | } 9 | 10 | // when used copy-and-swap 11 | 12 | // call constructor 13 | // call constructor 14 | // call constructor 15 | // call copy constructor !!! 16 | // call swap !!! 17 | // call destructor !!! 18 | // call move constructor !!! 19 | // call swap !!! 20 | // call destructor !!! 21 | // call destructor 22 | // call destructor 23 | 24 | // when used two assignment operator. 25 | 26 | // call constructor 27 | // call constructor 28 | // call constructor 29 | // call copy assignment !!! 30 | // call move assignment !!! 31 | // call destructor 32 | // call destructor 33 | -------------------------------------------------------------------------------- /ch13/ex13_58.cpp: -------------------------------------------------------------------------------- 1 | // Write versions of class `Foo` with print statements in their sorted functions to test your answers to the previous two exercises. 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using std::vector; 8 | using std::sort; 9 | 10 | class Foo { 11 | public: 12 | Foo sorted()&&; 13 | Foo sorted() const&; 14 | 15 | private: 16 | vector data; 17 | }; 18 | 19 | Foo Foo::sorted() && 20 | { 21 | sort(data.begin(), data.end()); 22 | std::cout << "&&" << std::endl; // debug 23 | return *this; 24 | } 25 | 26 | Foo Foo::sorted() const & 27 | { 28 | // Foo ret(*this); 29 | // sort(ret.data.begin(), ret.data.end()); 30 | // return ret; 31 | 32 | std::cout << "const &" << std::endl; // debug 33 | 34 | // Foo ret(*this); 35 | // ret.sorted(); // Exercise 13.56 36 | // return ret; 37 | 38 | return Foo(*this).sorted(); // Exercise 13.57 39 | } 40 | 41 | int main() 42 | { 43 | Foo().sorted(); // call "&&" 44 | Foo f; 45 | f.sorted(); // call "const &" 46 | } 47 | -------------------------------------------------------------------------------- /ch14/ex14_02_sales_data.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_02_sales_data.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 << " " 29 | << item.avg_price(); 30 | return os; 31 | } 32 | 33 | Sales_data operator+(const Sales_data& lhs, const Sales_data& rhs) 34 | { 35 | Sales_data sum = lhs; 36 | sum += rhs; 37 | return sum; 38 | } 39 | -------------------------------------------------------------------------------- /ch14/ex14_02_sales_data_test.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_02_sales_data.h" 2 | 3 | int main() 4 | { 5 | Sales_data cp5; 6 | std::cin >> cp5; 7 | std::cout << cp5 << std::endl; 8 | } 9 | 10 | // compile 11 | // cc -g ex14_02_sales_data_test.cpp ex14_02_sales_data.cpp -std=c++11 -pedantic 12 | // -Wall -------------------------------------------------------------------------------- /ch14/ex14_05.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_05.h" 2 | 3 | std::istream& operator>>(std::istream& in, Book& book) 4 | { 5 | in >> book.no_ >> book.name_ >> book.author_ >> book.pubdate_; 6 | if (!in) book = Book(); 7 | return in; 8 | } 9 | 10 | std::ostream& operator<<(std::ostream& out, const Book& book) 11 | { 12 | out << book.no_ << " " << book.name_ << " " << book.author_ << " " 13 | << book.pubdate_; 14 | return out; 15 | } 16 | 17 | bool operator==(const Book& lhs, const Book& rhs) 18 | { 19 | return lhs.no_ == rhs.no_; 20 | } 21 | 22 | bool operator!=(const Book& lhs, const Book& rhs) 23 | { 24 | return !(lhs == rhs); 25 | } 26 | -------------------------------------------------------------------------------- /ch14/ex14_05.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOK_H 2 | #define BOOK_H 3 | 4 | #include 5 | #include 6 | 7 | class Book { 8 | friend std::istream& operator>>(std::istream&, Book&); 9 | friend std::ostream& operator<<(std::ostream&, const Book&); 10 | friend bool operator==(const Book&, const Book&); 11 | friend bool operator!=(const Book&, const Book&); 12 | 13 | public: 14 | Book() = default; 15 | Book(unsigned no, std::string name, std::string author, std::string pubdate) 16 | : no_(no), name_(name), author_(author), pubdate_(pubdate) 17 | { 18 | } 19 | Book(std::istream& in) { in >> *this; } 20 | 21 | private: 22 | unsigned no_; 23 | std::string name_; 24 | std::string author_; 25 | std::string pubdate_; 26 | }; 27 | 28 | std::istream& operator>>(std::istream&, Book&); 29 | std::ostream& operator<<(std::ostream&, const Book&); 30 | bool operator==(const Book&, const Book&); 31 | bool operator!=(const Book&, const Book&); 32 | 33 | #endif // BOOK_H 34 | -------------------------------------------------------------------------------- /ch14/ex14_05_TEST.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_05.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) std::cout << book1 << std::endl; 9 | } 10 | -------------------------------------------------------------------------------- /ch14/ex14_07.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_STRING_H__ 2 | #define CP5_STRING_H__ 3 | 4 | #include 5 | #include 6 | 7 | class String { 8 | friend std::ostream& operator<<(std::ostream&, const String&); 9 | 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 35 | -------------------------------------------------------------------------------- /ch14/ex14_07_TEST.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_07.h" 2 | 3 | int main() 4 | { 5 | String str("Hello World"); 6 | std::cout << str << std::endl; 7 | } 8 | -------------------------------------------------------------------------------- /ch14/ex14_15_TEST.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_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 | } 10 | -------------------------------------------------------------------------------- /ch14/ex14_16_StrBlobTest.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_16_StrBlob.h" 2 | #include 3 | 4 | int main() 5 | { 6 | StrBlob sb{"Hello", "World", "Pezy"}; 7 | 8 | for (ConstStrBlobPtr iter = sb.cbegin(); iter != sb.cend(); iter.incr()) { 9 | std::cout << iter.deref() << " "; 10 | } 11 | std::cout << std::endl; 12 | } 13 | -------------------------------------------------------------------------------- /ch14/ex14_18_StrBlobTest.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_18_StrBlob.h" 2 | #include 3 | 4 | int main() 5 | { 6 | StrBlob sb1{"a", "b", "c"}; 7 | StrBlob sb2{"a", "b", "b"}; 8 | 9 | if (sb1 > sb2) { 10 | for (ConstStrBlobPtr iter = sb1.cbegin(); iter < sb1.cend(); 11 | iter.incr()) 12 | std::cout << iter.deref() << " "; 13 | std::cout << std::endl; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ch14/ex14_22_sales_data.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_22_sales_data.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 << " " 29 | << item.avg_price(); 30 | return os; 31 | } 32 | 33 | Sales_data operator+(const Sales_data& lhs, const Sales_data& rhs) 34 | { 35 | Sales_data sum = lhs; 36 | sum += rhs; 37 | return sum; 38 | } 39 | 40 | Sales_data& Sales_data::operator=(const std::string& isbn) 41 | { 42 | *this = Sales_data(isbn); 43 | return *this; 44 | } 45 | -------------------------------------------------------------------------------- /ch14/ex14_22_sales_data_test.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_22_sales_data.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 | } 9 | -------------------------------------------------------------------------------- /ch14/ex14_26_StrBlobTest.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_26_StrBlob.h" 2 | #include 3 | 4 | int main() 5 | { 6 | StrBlob sb1{"a", "b", "c"}; 7 | StrBlob sb2 = sb1; 8 | 9 | sb2[2] = "b"; 10 | 11 | if (sb1 > sb2) { 12 | for (ConstStrBlobPtr iter = sb1.cbegin(); iter < sb1.cend(); 13 | iter.incr()) 14 | std::cout << iter.deref() << " "; 15 | std::cout << std::endl; 16 | } 17 | 18 | StrBlobPtr iter(sb2); 19 | std::cout << iter[2] << std::endl; 20 | } 21 | -------------------------------------------------------------------------------- /ch14/ex14_27_28_StrBlobTest.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_27_28_StrBlob.h" 2 | #include 3 | 4 | int main() 5 | { 6 | StrBlob sb1{"a", "b", "c"}; 7 | StrBlob sb2 = sb1; 8 | 9 | sb2[2] = "b"; 10 | 11 | if (sb1 > sb2) { 12 | for (StrBlobPtr iter = sb1.begin(); iter < sb1.end(); ++iter) 13 | std::cout << iter.deref() << " "; 14 | std::cout << std::endl; 15 | } 16 | 17 | ConstStrBlobPtr iter(sb2); 18 | std::cout << (iter + 2).deref() << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /ch14/ex14_30_StrBlobTest.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_30_StrBlob.h" 2 | #include 3 | 4 | int main() 5 | { 6 | StrBlob sb1{"a", "b", "c"}; 7 | StrBlob sb2 = sb1; 8 | 9 | sb2[2] = "b"; 10 | 11 | if (sb1 > sb2) { 12 | for (ConstStrBlobPtr iter = sb1.cbegin(); iter != sb1.cend(); ++iter) 13 | std::cout << *iter << " "; 14 | std::cout << std::endl; 15 | } 16 | 17 | ConstStrBlobPtr iter(sb2); 18 | std::cout << iter->size() << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /ch14/ex14_32.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_32.h" 2 | #include "ex14_30_StrBlob.h" 3 | #include 4 | 5 | StrBlobPtr& StrBlobPtr_pointer::operator*() 6 | { 7 | return *(this->pointer); 8 | } 9 | 10 | StrBlobPtr* StrBlobPtr_pointer::operator->() 11 | { 12 | return &this->operator*(); 13 | } 14 | 15 | int main() 16 | { 17 | StrBlob sb{"hello", "world"}; 18 | StrBlobPtr iter = sb.begin(); 19 | StrBlobPtr_pointer p(&iter); 20 | std::cout << p->deref() << std::endl; 21 | } 22 | -------------------------------------------------------------------------------- /ch14/ex14_32.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file StrBlobPtr_pointer.h 3 | * @author Alan.W 4 | * @date 19 JAN 2014 5 | * @remark a class that holds a pointer to a StrBlobPtr. 6 | ***************************************************************************/ 7 | 8 | #ifndef STRBLOBPTR_POINTER_H 9 | #define STRBLOBPTR_POINTER_H 10 | 11 | class StrBlobPtr; 12 | 13 | /** 14 | * @brief a class that holds a pointer to a StrBlobPtr. 15 | */ 16 | class StrBlobPtr_pointer { 17 | public: 18 | StrBlobPtr_pointer() = default; 19 | StrBlobPtr_pointer(StrBlobPtr* p) : pointer(p) {} 20 | 21 | StrBlobPtr& operator*(); 22 | StrBlobPtr* operator->(); 23 | 24 | private: 25 | StrBlobPtr* pointer = nullptr; 26 | }; 27 | 28 | #endif // STRBLOBPTR_POINTER_H 29 | -------------------------------------------------------------------------------- /ch14/ex14_35.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class GetInput { 5 | public: 6 | GetInput(std::istream& i = std::cin) : is(i) {} 7 | std::string operator()() const 8 | { 9 | std::string str; 10 | std::getline(is, str); 11 | return is ? str : std::string(); 12 | } 13 | 14 | private: 15 | std::istream& is; 16 | }; 17 | 18 | int main() 19 | { 20 | GetInput getInput; 21 | std::cout << getInput() << std::endl; 22 | } 23 | -------------------------------------------------------------------------------- /ch14/ex14_36.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class GetInput { 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::vector vec; 23 | for (std::string tmp; !(tmp = getInput()).empty();) vec.push_back(tmp); 24 | for (const auto& str : vec) std::cout << str << " "; 25 | std::cout << std::endl; 26 | } 27 | -------------------------------------------------------------------------------- /ch14/ex14_37.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class IsEqual { 6 | int value; 7 | 8 | public: 9 | IsEqual(int v) : value(v) {} 10 | bool operator()(int elem) { return elem == value; } 11 | }; 12 | 13 | int main() 14 | { 15 | std::vector vec = {3, 2, 1, 4, 3, 7, 8, 6}; 16 | std::replace_if(vec.begin(), vec.end(), IsEqual(3), 5); 17 | for (int i : vec) std::cout << i << " "; 18 | std::cout << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /ch14/ex14_42.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main() 8 | { 9 | using std::placeholders::_1; 10 | 11 | std::vector ivec{1, 111, 1111, 11111}; 12 | int count = std::count_if(ivec.cbegin(), ivec.cend(), 13 | std::bind(std::greater(), _1, 1024)); 14 | std::cout << count << std::endl; 15 | 16 | std::vector svec{"pooh", "pooh", "pezy", "pooh"}; 17 | auto found = 18 | std::find_if(svec.cbegin(), svec.cend(), 19 | std::bind(std::not_equal_to(), _1, "pooh")); 20 | std::cout << *found << std::endl; 21 | 22 | std::transform(ivec.begin(), ivec.end(), ivec.begin(), 23 | std::bind(std::multiplies(), _1, 2)); 24 | for (int i : ivec) std::cout << i << " "; 25 | std::cout << std::endl; 26 | } 27 | -------------------------------------------------------------------------------- /ch14/ex14_43.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file main.cpp 3 | * @author XDXX, Yue Wang 4 | * @date 5/24/2015 5 | * @remark This code is for the exercises from C++ Primer 5th Edition 6 | * @note 7 | ***************************************************************************/ 8 | //! 9 | //! Exercise 14.43: 10 | //! Using library function objects, determine whether a given int value is 11 | //! divisible by any element in a container of ints. 12 | //! 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | int main() 20 | { 21 | auto data = {2, 3, 4, 5}; 22 | int input; 23 | std::cin >> input; 24 | std::modulus mod; 25 | auto predicator = [&](int i) { return 0 == mod(input, i); }; 26 | auto is_divisible = std::any_of(data.begin(), data.end(), predicator); 27 | std::cout << (is_divisible ? "Yes!" : "No!") << std::endl; 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /ch14/ex14_45_sales_data.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_45_sales_data.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 << " " 29 | << item.avg_price(); 30 | return os; 31 | } 32 | 33 | Sales_data operator+(const Sales_data& lhs, const Sales_data& rhs) 34 | { 35 | Sales_data sum = lhs; 36 | sum += rhs; 37 | return sum; 38 | } 39 | 40 | Sales_data& Sales_data::operator=(const std::string& isbn) 41 | { 42 | *this = Sales_data(isbn); 43 | return *this; 44 | } 45 | -------------------------------------------------------------------------------- /ch14/ex14_45_sales_data_test.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_45_sales_data.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 | } 10 | -------------------------------------------------------------------------------- /ch14/ex14_49_TEST.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_49.h" 2 | 3 | int main() 4 | { 5 | Date date(12, 4, 2015); 6 | if (static_cast(date)) std::cout << date << std::endl; 7 | } 8 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/andquery.cpp: -------------------------------------------------------------------------------- 1 | #include "andquery.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/andquery.h: -------------------------------------------------------------------------------- 1 | #ifndef ANDQUERY_H 2 | #define ANDQUERY_H 3 | 4 | 5 | #include "binaryquery.h" 6 | 7 | class AndQuery : public BinaryQuery 8 | { 9 | friend Query operator&(const Query&, const Query&); 10 | AndQuery(const Query& left, const Query& right): 11 | BinaryQuery(left,right, "&") 12 | { 13 | std::cout << "AndQuery::AndQuery()\n"; 14 | } 15 | 16 | //! @note: inherits rep and define eval 17 | 18 | QueryResult eval(const TextQuery &) const override 19 | { 20 | // this is just a placeholder rather than the real definition 21 | } 22 | }; 23 | 24 | inline Query operator& (const Query& lhs, const Query& rhs) 25 | { 26 | return std::shared_ptr(new AndQuery(lhs,rhs)); 27 | } 28 | 29 | #endif // ANDQUERY_H 30 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/binaryquery.cpp: -------------------------------------------------------------------------------- 1 | #include "binaryquery.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/binaryquery.h: -------------------------------------------------------------------------------- 1 | #ifndef BINARYQUERY_H 2 | #define BINARYQUERY_H 3 | 4 | #include "query_base.h" 5 | #include "query.h" 6 | 7 | 8 | 9 | /** 10 | * @brief The BinaryQuery class 11 | *An abstract class holds data needed by the query types that operate on two operands 12 | */ 13 | class BinaryQuery : public Query_base 14 | { 15 | protected: 16 | BinaryQuery(const Query&l, const Query& r, std::string s): 17 | lhs(l), rhs(r), opSym(s) 18 | { 19 | std::cout << "BinaryQuery::BinaryQuery() where s=" + s + "\n"; 20 | } 21 | 22 | //! @note: abstract class: BinaryQuery doesn't define eval 23 | 24 | std::string rep() const override 25 | { 26 | std::cout << "BinaryQuery::rep()\n"; 27 | return "(" + lhs.rep() + " " 28 | + opSym + " " 29 | + rhs.rep() + ")"; 30 | } 31 | 32 | Query lhs, rhs; 33 | std::string opSym; 34 | }; 35 | 36 | #endif // BINARYQUERY_H 37 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/notquery.cpp: -------------------------------------------------------------------------------- 1 | #include "notquery.h" 2 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/orquery.cpp: -------------------------------------------------------------------------------- 1 | #include "orquery.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/orquery.h: -------------------------------------------------------------------------------- 1 | #ifndef ORQUERY_H 2 | #define ORQUERY_H 3 | 4 | #include "binaryquery.h" 5 | 6 | class OrQuery :public BinaryQuery 7 | { 8 | friend Query operator|(const Query&, const Query&); 9 | OrQuery(const Query& left, const Query& right): 10 | BinaryQuery(left, right, "|") 11 | { 12 | std::cout << "OrQuery::OrQuery\n"; 13 | } 14 | 15 | QueryResult eval(const TextQuery& )const override 16 | { 17 | //place holder 18 | } 19 | }; 20 | 21 | inline Query operator|(const Query &lhs, const Query& rhs) 22 | { 23 | return std::shared_ptr(new OrQuery(lhs, rhs)); 24 | } 25 | 26 | #endif // ORQUERY_H 27 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/query.cpp: -------------------------------------------------------------------------------- 1 | #include "query.h" 2 | 3 | 4 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/query_base.cpp: -------------------------------------------------------------------------------- 1 | #include "query_base.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/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 26 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/queryresult.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file queryresult.cpp 3 | * @author Alan.W 4 | * @date 30 DEC 2013 5 | * @remark using class StrBlob 6 | ***************************************************************************/ 7 | 8 | 9 | #include "queryresult.h" 10 | 11 | 12 | /** 13 | * @brief print the result to the output stream specified. 14 | * @note class QueryResult's friend 15 | */ 16 | std::ostream 17 | &print(std::ostream &os, const QueryResult &qr) 18 | { 19 | os << qr.sought << " occurs " << qr.sp_lines->size() << " " 20 | << "times" << "\n"; 21 | 22 | //! print each line in which the word appears 23 | for ( auto &index : *qr.sp_lines) 24 | { 25 | os << "\t(line " << index + 1 << ") "; 26 | const StrBlobPtr wp(qr.file, index); 27 | os << wp.deref() << "\n"; 28 | } 29 | return os; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/wordquery.cpp: -------------------------------------------------------------------------------- 1 | #include "wordquery.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/wordquery.h: -------------------------------------------------------------------------------- 1 | #ifndef WORDQUERY_H 2 | #define WORDQUERY_H 3 | 4 | #include "query_base.h" 5 | 6 | /** 7 | * @brief The WordQuery class 8 | *The only class that actually performs a query on the given TextQuery object. 9 | *No public members defined in this class. All operation are through the friend 10 | *class Query. 11 | */ 12 | class WordQuery : public Query_base 13 | { 14 | //! class Query uses the WordQuery constructor 15 | friend class Query; 16 | WordQuery(const std::string& s): 17 | query_word(s) 18 | { 19 | std::cout << "WordQuery::WordQuery(" + s + ")\n"; 20 | } 21 | 22 | 23 | //! virtuals: 24 | QueryResult eval(const TextQuery& t) const override 25 | { return t.query(query_word); } 26 | std::string rep() const override 27 | { 28 | std::cout << "WodQuery::rep()\n"; 29 | return query_word; 30 | } 31 | 32 | 33 | std::string query_word; 34 | }; 35 | 36 | #endif // WORDQUERY_H 37 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/andquery.cpp: -------------------------------------------------------------------------------- 1 | #include "andquery.h" 2 | #include 3 | #include 4 | /** 5 | * @brief AndQuery::eval 6 | * @return the intersection of its operands' result sets 7 | */ 8 | QueryResult AndQuery::eval(const TextQuery &text) const 9 | { 10 | //! virtual calls through the Query operands to get result sets for the operands 11 | QueryResult left = lhs.eval(text), right = rhs.eval(text); 12 | 13 | //! set to hold the intersection of the left and right 14 | std::shared_ptr> 15 | ret_lines = std::make_shared>(); 16 | 17 | //! writes the intersection of two ranges to a destination iterator 18 | std::set_intersection(left.begin(), left.end(), 19 | right.begin(), right.end(), 20 | std::inserter(*ret_lines, ret_lines->begin())); 21 | 22 | return QueryResult(rep(), ret_lines, left.get_file()); 23 | } 24 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/andquery.h: -------------------------------------------------------------------------------- 1 | #ifndef ANDQUERY_H 2 | #define ANDQUERY_H 3 | 4 | 5 | #include "binaryquery.h" 6 | 7 | class AndQuery : public BinaryQuery 8 | { 9 | friend Query operator&(const Query&, const Query&); 10 | AndQuery(const Query& left, const Query& right): 11 | BinaryQuery(left,right, "&") 12 | { 13 | std::cout << "AndQuery::AndQuery()\n"; 14 | } 15 | 16 | //! @note: inherits rep and define eval 17 | 18 | QueryResult eval(const TextQuery &) const override; 19 | }; 20 | 21 | inline Query operator& (const Query& lhs, const Query& rhs) 22 | { 23 | return std::shared_ptr(new AndQuery(lhs,rhs)); 24 | } 25 | 26 | #endif // ANDQUERY_H 27 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/binaryquery.cpp: -------------------------------------------------------------------------------- 1 | #include "binaryquery.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/binaryquery.h: -------------------------------------------------------------------------------- 1 | #ifndef BINARYQUERY_H 2 | #define BINARYQUERY_H 3 | 4 | #include "query_base.h" 5 | #include "query.h" 6 | 7 | 8 | 9 | /** 10 | * @brief The BinaryQuery class 11 | *An abstract class holds data needed by the query types that operate on two operands 12 | */ 13 | class BinaryQuery : public Query_base 14 | { 15 | protected: 16 | BinaryQuery(const Query&l, const Query& r, std::string s): 17 | lhs(l), rhs(r), opSym(s) 18 | { 19 | std::cout << "BinaryQuery::BinaryQuery() where s=" + s + "\n"; 20 | } 21 | 22 | //! @note: abstract class: BinaryQuery doesn't define eval 23 | 24 | std::string rep() const override 25 | { 26 | std::cout << "BinaryQuery::rep()\n"; 27 | return "(" + lhs.rep() + " " 28 | + opSym + " " 29 | + rhs.rep() + ")"; 30 | } 31 | 32 | Query lhs, rhs; 33 | std::string opSym; 34 | }; 35 | 36 | #endif // BINARYQUERY_H 37 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/notquery.cpp: -------------------------------------------------------------------------------- 1 | #include "notquery.h" 2 | #include 3 | /** 4 | * @brief NotQuery::eval 5 | * @return the lines not in its operand's result set 6 | */ 7 | QueryResult NotQuery::eval(const TextQuery &text) const 8 | { 9 | //! virtual call to eval through the Query operand 10 | QueryResult result = query.eval(text); 11 | 12 | //! start out with an empty result set 13 | std::shared_ptr> 14 | ret_lines = std::make_shared>(); 15 | 16 | std::set::iterator 17 | begin = result.begin(), 18 | end = result.end(); 19 | 20 | StrBlob::size_type sz = result.get_file().size(); 21 | 22 | for(std::size_t n = 0; n != sz; ++n) 23 | { 24 | if(begin == end || *begin != n) 25 | ret_lines->insert(n); 26 | else if (begin != end) 27 | ++begin; 28 | } 29 | 30 | return QueryResult(rep(), ret_lines, result.get_file()); 31 | } 32 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/orquery.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "orquery.h" 3 | 4 | 5 | QueryResult OrQuery::eval(const TextQuery &text) const 6 | { 7 | QueryResult right = rhs.eval(text), left= lhs.eval(text); 8 | 9 | //! copy the left-hand operand into the result set 10 | std::shared_ptr> ret_lines = 11 | std::make_shared>(left.begin(), left.end()); 12 | 13 | //! inert lines from the right-hand operand 14 | ret_lines->insert(right.begin(), right.end()); 15 | 16 | return QueryResult(rep(),ret_lines,left.get_file()); 17 | } 18 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/orquery.h: -------------------------------------------------------------------------------- 1 | #ifndef ORQUERY_H 2 | #define ORQUERY_H 3 | 4 | #include "binaryquery.h" 5 | 6 | class OrQuery :public BinaryQuery 7 | { 8 | friend Query operator|(const Query&, const Query&); 9 | OrQuery(const Query& left, const Query& right): 10 | BinaryQuery(left, right, "|") 11 | { 12 | std::cout << "OrQuery::OrQuery\n"; 13 | } 14 | 15 | QueryResult eval(const TextQuery& )const override; 16 | }; 17 | 18 | inline Query operator|(const Query &lhs, const Query& rhs) 19 | { 20 | return std::shared_ptr(new OrQuery(lhs, rhs)); 21 | } 22 | 23 | #endif // ORQUERY_H 24 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/query.cpp: -------------------------------------------------------------------------------- 1 | #include "query.h" 2 | 3 | 4 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/query_base.cpp: -------------------------------------------------------------------------------- 1 | #include "query_base.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/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 26 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/queryresult.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file queryresult.cpp 3 | * @author Alan.W 4 | * @date 30 DEC 2013 5 | * @remark using class StrBlob 6 | ***************************************************************************/ 7 | 8 | 9 | #include "queryresult.h" 10 | 11 | 12 | /** 13 | * @brief print the result to the output stream specified. 14 | * @note class QueryResult's friend 15 | */ 16 | std::ostream& 17 | operator <<(std::ostream &os, const QueryResult &qr) 18 | { 19 | os << qr.sought << " occurs " << qr.sp_lines->size() << " " 20 | << "times" << "\n"; 21 | 22 | //! print each line in which the word appears 23 | for ( auto &index : *qr.sp_lines) 24 | { 25 | os << "\t(line " << index + 1 << ") "; 26 | const StrBlobPtr wp(qr.file, index); 27 | os << wp.deref() << "\n"; 28 | } 29 | return os; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/wordquery.cpp: -------------------------------------------------------------------------------- 1 | #include "wordquery.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/wordquery.h: -------------------------------------------------------------------------------- 1 | #ifndef WORDQUERY_H 2 | #define WORDQUERY_H 3 | 4 | #include "query_base.h" 5 | 6 | /** 7 | * @brief The WordQuery class 8 | *The only class that actually performs a query on the given TextQuery object. 9 | *No public members defined in this class. All operation are through the friend 10 | *class Query. 11 | */ 12 | class WordQuery : public Query_base 13 | { 14 | //! class Query uses the WordQuery constructor 15 | friend class Query; 16 | WordQuery(const std::string& s): 17 | query_word(s) 18 | { 19 | std::cout << "WordQuery::WordQuery(" + s + ")\n"; 20 | } 21 | 22 | 23 | //! virtuals: 24 | QueryResult eval(const TextQuery& t) const override 25 | { return t.query(query_word); } 26 | std::string rep() const override 27 | { 28 | std::cout << "WodQuery::rep()\n"; 29 | return query_word; 30 | } 31 | 32 | 33 | std::string query_word; 34 | }; 35 | 36 | #endif // WORDQUERY_H 37 | -------------------------------------------------------------------------------- /ch15/ex15.42_b/andquery.cpp: -------------------------------------------------------------------------------- 1 | #include"andquery.h" 2 | 3 | #include 4 | using std::set_intersection; 5 | 6 | #include 7 | using std::inserter; 8 | 9 | #include 10 | using std::make_shared; 11 | 12 | #include 13 | using std::set; 14 | 15 | #include"queryresult.h" 16 | #include"textquery.h" 17 | #include"query.h" 18 | 19 | QueryResult 20 | AndQuery::eval(const TextQuery& text) const 21 | { 22 | auto left = lhs.eval(text); 23 | auto right = rhs.eval(text); 24 | 25 | auto ret_lines = make_shared>(); 26 | 27 | set_intersection(left.begin(), left.end(), right.begin(), right.end(), inserter(*ret_lines, ret_lines->begin())); 28 | 29 | return QueryResult(rep(), ret_lines, left.get_file()); 30 | } -------------------------------------------------------------------------------- /ch15/ex15.42_b/andquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _ANDQUERY_H 2 | #define _ANDQUERY_H 3 | 4 | #include 5 | using std::shared_ptr; 6 | 7 | #include"query.h" 8 | #include"binaryquery.h" 9 | 10 | class QueryResult; 11 | class TextQuery; 12 | 13 | class AndQuery :public BinaryQuery 14 | { 15 | friend Query operator&(const Query&, const Query&); 16 | AndQuery(const Query &left, const Query &right) :BinaryQuery(left, right, "&"){} 17 | QueryResult eval(const TextQuery&) const; 18 | }; 19 | 20 | inline Query operator&(const Query &lhs, const Query &rhs) 21 | { 22 | return shared_ptr(new AndQuery(lhs, rhs)); 23 | } 24 | 25 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_b/binaryquery.cpp: -------------------------------------------------------------------------------- 1 | #include"binaryquery.h" -------------------------------------------------------------------------------- /ch15/ex15.42_b/binaryquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _BINARYQUERY_H 2 | #define _BINARYQUERY_H 3 | 4 | #include 5 | using std::string; 6 | 7 | #include"query.h" 8 | #include"query_base.h" 9 | 10 | 11 | class BinaryQuery :public Query_base 12 | { 13 | protected: 14 | BinaryQuery(const Query &l, const Query &r, string s) :lhs(l), rhs(r), opSym(s){} 15 | string rep() const 16 | { 17 | return "(" + lhs.rep() + " " + opSym + " " + rhs.rep() + ")"; 18 | } 19 | 20 | Query lhs, rhs; 21 | string opSym; 22 | }; 23 | 24 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_b/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::cout; using std::cin; using std::endl; 3 | 4 | #include 5 | using std::ifstream; 6 | 7 | #include 8 | using std::string; 9 | 10 | #include 11 | using std::vector; 12 | 13 | #include"queryhistory.h" 14 | #include"queryresult.h" 15 | #include"textquery.h" 16 | #include"query.h" 17 | #include"andquery.h" 18 | #include"orquery.h" 19 | #include"notquery.h" 20 | 21 | int main() 22 | { 23 | ifstream fin("test.txt"); 24 | TextQuery text(fin); 25 | QueryHistory history; 26 | Query q0("Alice"); 27 | Query q1("hair"); 28 | Query q2("Daddy"); 29 | 30 | history.add_query(q0); 31 | history.add_query(q1); 32 | history[0] = history[0] | q2; 33 | 34 | auto result = history[0].eval(text); 35 | print(cout, result); 36 | 37 | return 0; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /ch15/ex15.42_b/notquery.cpp: -------------------------------------------------------------------------------- 1 | #include"notquery.h" 2 | 3 | #include 4 | using std::make_shared; 5 | 6 | #include 7 | using std::set; 8 | 9 | #include"queryresult.h" 10 | #include"textquery.h" 11 | #include"query.h" 12 | 13 | 14 | QueryResult 15 | NotQuery::eval(const TextQuery &text) const 16 | { 17 | auto result = query.eval(text); 18 | 19 | auto ret_lines = make_shared>(); 20 | 21 | auto beg = result.begin(); 22 | auto end = result.end(); 23 | 24 | auto sz = result.get_file()->size(); 25 | for (size_t n = 0; n != sz; ++n) 26 | { 27 | if (beg == end || *beg != n) 28 | ret_lines->insert(n); 29 | else if (beg != end) 30 | ++beg; 31 | } 32 | return QueryResult(rep(), ret_lines, result.get_file()); 33 | } -------------------------------------------------------------------------------- /ch15/ex15.42_b/notquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _NOTQUERY_H 2 | #define _NOTQUERY_H 3 | 4 | #include 5 | using std::shared_ptr; 6 | 7 | #include 8 | using std::string; 9 | 10 | #include"query.h" 11 | #include"query_base.h" 12 | 13 | class QueryResult; 14 | class TextQuery; 15 | 16 | class NotQuery :public Query_base 17 | { 18 | friend Query operator~(const Query&); 19 | //call Query's default copy constructor. 20 | NotQuery(const Query &q) :query(q){} 21 | string rep() const{ return "~(" + query.rep() + ")"; } 22 | QueryResult eval(const TextQuery&) const; 23 | 24 | Query query; 25 | }; 26 | 27 | inline Query operator~(const Query &operand) 28 | { 29 | return shared_ptr(new NotQuery(operand)); 30 | } 31 | 32 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_b/orquery.cpp: -------------------------------------------------------------------------------- 1 | #include"orquery.h" 2 | 3 | #include 4 | using std::make_shared; 5 | 6 | #include 7 | using std::set; 8 | 9 | #include"queryresult.h" 10 | #include"textquery.h" 11 | #include"query.h" 12 | 13 | QueryResult 14 | OrQuery::eval(const TextQuery &text) const 15 | { 16 | auto right = rhs.eval(text); 17 | auto left = lhs.eval(text); 18 | auto ret_lines = make_shared>(left.begin(), left.end()); 19 | ret_lines->insert(right.begin(), right.end()); 20 | return QueryResult(rep(), ret_lines, left.get_file()); 21 | } -------------------------------------------------------------------------------- /ch15/ex15.42_b/orquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _ORQUERY_H 2 | #define _ORQUERY_H 3 | 4 | #include 5 | using std::shared_ptr; 6 | 7 | #include"query.h" 8 | #include"binaryquery.h" 9 | 10 | class QueryResult; 11 | class TextQuery; 12 | 13 | class OrQuery :public BinaryQuery 14 | { 15 | friend Query operator|(const Query&, const Query&); 16 | OrQuery(const Query &left, const Query &right) :BinaryQuery(left, right, "|"){} 17 | QueryResult eval(const TextQuery&) const; 18 | }; 19 | 20 | inline Query operator|(const Query &lhs, const Query &rhs) 21 | { 22 | return shared_ptr(new OrQuery(lhs, rhs)); 23 | } 24 | 25 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_b/query.cpp: -------------------------------------------------------------------------------- 1 | #include"query.h" 2 | 3 | #include 4 | using std::ostream; 5 | 6 | ostream& 7 | operator<<(ostream &os, const Query &query) 8 | { 9 | return os << query.rep(); 10 | } -------------------------------------------------------------------------------- /ch15/ex15.42_b/query.h: -------------------------------------------------------------------------------- 1 | #ifndef _QUERY_H 2 | #define _QUERY_H 3 | 4 | #include 5 | using std::ostream; 6 | 7 | #include 8 | using std::shared_ptr; 9 | 10 | #include 11 | using std::string; 12 | 13 | #include"query_base.h" 14 | #include"queryresult.h" 15 | #include"wordquery.h" 16 | 17 | 18 | class TextQuery; 19 | 20 | class Query 21 | { 22 | friend Query operator~(const Query&); 23 | friend Query operator|(const Query&, const Query&); 24 | friend Query operator&(const Query&, const Query&); 25 | public: 26 | Query(const string&); 27 | //call QueryResult's default copy constructor. 28 | QueryResult eval(const TextQuery &t) const { return q->eval(t); } 29 | string rep() const { return q->rep(); } 30 | private: 31 | Query(shared_ptr query) :q(query){} 32 | shared_ptr q; 33 | }; 34 | 35 | ostream & operator<<(ostream &os, const Query &query); 36 | 37 | inline Query::Query(const string &s) :q(new WordQuery(s)){} 38 | 39 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_b/query_base.cpp: -------------------------------------------------------------------------------- 1 | #include"query_base.h" -------------------------------------------------------------------------------- /ch15/ex15.42_b/query_base.h: -------------------------------------------------------------------------------- 1 | #ifndef _QUERY_BASE_H 2 | #define _QUERY_BASE_H 3 | 4 | #include 5 | using std::string; 6 | 7 | #include"textquery.h" 8 | 9 | class Query_base 10 | { 11 | friend class Query; 12 | protected: 13 | using line_no = TextQuery::line_no; 14 | virtual ~Query_base() = default; 15 | private: 16 | virtual QueryResult eval(const TextQuery&) const = 0; 17 | virtual string rep() const = 0; 18 | }; 19 | 20 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_b/queryhistory.cpp: -------------------------------------------------------------------------------- 1 | #include"queryhistory.h" 2 | 3 | #include 4 | using std::shared_ptr; using std::make_shared; 5 | 6 | size_t QueryHistory::add_query(const Query &query) 7 | { 8 | shared_ptr p = make_shared(query); 9 | query_vec.push_back(p); 10 | return query_vec.size() - 1; 11 | } -------------------------------------------------------------------------------- /ch15/ex15.42_b/queryhistory.h: -------------------------------------------------------------------------------- 1 | #ifndef _QUERYHISTORY_H 2 | #define _QUERYHISTORY_H 3 | 4 | #include 5 | using std::shared_ptr; 6 | 7 | #include 8 | using std::vector; 9 | 10 | #include"query.h" 11 | 12 | class QueryHistory 13 | { 14 | public: 15 | Query& operator[](size_t n) 16 | { 17 | return *(query_vec[n]); 18 | } 19 | 20 | //return the assigned number of the new query 21 | size_t add_query(const Query&); 22 | private: 23 | vector> query_vec; 24 | }; 25 | 26 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_b/queryresult.cpp: -------------------------------------------------------------------------------- 1 | #include "queryresult.h" 2 | 3 | #include 4 | using std::ostream; 5 | 6 | ostream& 7 | print(ostream &os, const QueryResult &qr) 8 | { 9 | os <<"The result of your query "<< qr.sought <<" is: \n"; 10 | for (const auto &index: *qr.lines) 11 | os << "\t(line " << index + 1 << ")" 12 | << *(qr.file->begin() + index) << "\n"; 13 | return os; 14 | } 15 | -------------------------------------------------------------------------------- /ch15/ex15.42_b/queryresult.h: -------------------------------------------------------------------------------- 1 | #ifndef _QUERYRESULT_H 2 | #define _QUERYRESULT_H 3 | 4 | #include 5 | using std::ostream; 6 | 7 | #include 8 | using std::shared_ptr; 9 | 10 | #include 11 | using std::set; 12 | 13 | #include 14 | using std::vector; 15 | 16 | #include 17 | using std::string; 18 | 19 | #include "textquery.h" 20 | 21 | 22 | class QueryResult 23 | { 24 | friend ostream& print(ostream&, const QueryResult&); 25 | 26 | public: 27 | QueryResult(string s, 28 | shared_ptr> l, 29 | shared_ptr> f) : 30 | sought(s), lines(l), file(f){} 31 | 32 | set::iterator begin(){ return lines->begin(); } 33 | set::iterator end(){ return lines->end(); } 34 | shared_ptr> get_file(){ return file; } 35 | 36 | private: 37 | string sought; 38 | shared_ptr> lines; 39 | shared_ptr> file; 40 | }; 41 | 42 | ostream& 43 | print(ostream&, const QueryResult&); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /ch15/ex15.42_b/test.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?" -------------------------------------------------------------------------------- /ch15/ex15.42_b/textquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _TEXTQUERY_H 2 | #define _TEXTQUERY_H 3 | 4 | #include 5 | using std::ifstream; 6 | 7 | #include 8 | using std::shared_ptr; 9 | 10 | #include 11 | using std::vector; 12 | 13 | #include 14 | using std::string; 15 | 16 | #include 17 | using std::map; 18 | 19 | #include 20 | using std::set; 21 | 22 | class QueryResult; 23 | 24 | class TextQuery 25 | { 26 | 27 | public: 28 | typedef vector::size_type line_no; 29 | 30 | TextQuery(ifstream&); 31 | QueryResult query(const string&) const; 32 | 33 | private: 34 | shared_ptr> file; 35 | map>> wm; 36 | 37 | shared_ptr> handlePunct(const string&); 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /ch15/ex15.42_b/wordquery.cpp: -------------------------------------------------------------------------------- 1 | #include"wordquery.h" -------------------------------------------------------------------------------- /ch15/ex15.42_b/wordquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _WORDQUERY_H 2 | #define _WORDQUERY_H 3 | 4 | #include 5 | using std::string; 6 | 7 | #include"query_base.h" 8 | #include"queryresult.h" 9 | #include"textquery.h" 10 | 11 | class WordQuery:public Query_base 12 | { 13 | friend class Query; 14 | WordQuery(const string &s) :query_word(s){} 15 | QueryResult eval(const TextQuery &t) const{ return t.query(query_word); } 16 | string rep() const { return query_word; } 17 | 18 | string query_word; 19 | }; 20 | 21 | 22 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_c/andquery.cpp: -------------------------------------------------------------------------------- 1 | #include"andquery.h" 2 | 3 | #include 4 | using std::set_intersection; 5 | 6 | #include 7 | using std::inserter; 8 | 9 | #include 10 | using std::make_shared; 11 | 12 | #include 13 | using std::set; 14 | 15 | #include"queryresult.h" 16 | #include"textquery.h" 17 | #include"query.h" 18 | 19 | QueryResult 20 | AndQuery::eval(const TextQuery& text) const 21 | { 22 | auto left = lhs.eval(text); 23 | auto right = rhs.eval(text); 24 | 25 | auto ret_lines = make_shared>(); 26 | 27 | set_intersection(left.begin(), left.end(), right.begin(), right.end(), inserter(*ret_lines, ret_lines->begin())); 28 | 29 | return QueryResult(rep(), ret_lines, left.get_file()); 30 | } -------------------------------------------------------------------------------- /ch15/ex15.42_c/andquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _ANDQUERY_H 2 | #define _ANDQUERY_H 3 | 4 | #include 5 | using std::shared_ptr; 6 | 7 | #include"query.h" 8 | #include"binaryquery.h" 9 | 10 | class QueryResult; 11 | class TextQuery; 12 | 13 | class AndQuery :public BinaryQuery 14 | { 15 | friend Query operator&(const Query&, const Query&); 16 | AndQuery(const Query &left, const Query &right) :BinaryQuery(left, right, "&"){} 17 | QueryResult eval(const TextQuery&) const; 18 | }; 19 | 20 | inline Query operator&(const Query &lhs, const Query &rhs) 21 | { 22 | return shared_ptr(new AndQuery(lhs, rhs)); 23 | } 24 | 25 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_c/binaryquery.cpp: -------------------------------------------------------------------------------- 1 | #include"binaryquery.h" -------------------------------------------------------------------------------- /ch15/ex15.42_c/binaryquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _BINARYQUERY_H 2 | #define _BINARYQUERY_H 3 | 4 | #include 5 | using std::string; 6 | 7 | #include"query.h" 8 | #include"query_base.h" 9 | 10 | 11 | class BinaryQuery :public Query_base 12 | { 13 | protected: 14 | BinaryQuery(const Query &l, const Query &r, string s) :lhs(l), rhs(r), opSym(s){} 15 | string rep() const 16 | { 17 | return "(" + lhs.rep() + " " + opSym + " " + rhs.rep() + ")"; 18 | } 19 | 20 | Query lhs, rhs; 21 | string opSym; 22 | }; 23 | 24 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_c/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::cout; using std::cin; using std::endl; 3 | 4 | #include 5 | using std::ifstream; 6 | 7 | #include 8 | using std::string; 9 | 10 | #include 11 | using std::vector; 12 | 13 | #include"queryresult.h" 14 | #include"textquery.h" 15 | #include"query.h" 16 | #include"andquery.h" 17 | #include"orquery.h" 18 | #include"notquery.h" 19 | 20 | int main() 21 | { 22 | ifstream fin("test.txt"); 23 | TextQuery text(fin); 24 | auto q = ~Query("Alice"); 25 | 26 | auto result = q.eval(text); 27 | print(cout, result); 28 | cout << endl; 29 | print(cout, result, -3, 5); 30 | cout << endl; 31 | print(cout, result, 3, 5); 32 | cout << endl; 33 | print(cout, result, 3, 20); 34 | cout << endl; 35 | 36 | return 0; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /ch15/ex15.42_c/notquery.cpp: -------------------------------------------------------------------------------- 1 | #include"notquery.h" 2 | 3 | #include 4 | using std::make_shared; 5 | 6 | #include 7 | using std::set; 8 | 9 | #include"queryresult.h" 10 | #include"textquery.h" 11 | #include"query.h" 12 | 13 | 14 | QueryResult 15 | NotQuery::eval(const TextQuery &text) const 16 | { 17 | auto result = query.eval(text); 18 | 19 | auto ret_lines = make_shared>(); 20 | 21 | auto beg = result.begin(); 22 | auto end = result.end(); 23 | 24 | auto sz = result.get_file()->size(); 25 | for (size_t n = 0; n != sz; ++n) 26 | { 27 | if (beg == end || *beg != n) 28 | ret_lines->insert(n); 29 | else if (beg != end) 30 | ++beg; 31 | } 32 | return QueryResult(rep(), ret_lines, result.get_file()); 33 | } -------------------------------------------------------------------------------- /ch15/ex15.42_c/notquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _NOTQUERY_H 2 | #define _NOTQUERY_H 3 | 4 | #include 5 | using std::shared_ptr; 6 | 7 | #include 8 | using std::string; 9 | 10 | #include"query.h" 11 | #include"query_base.h" 12 | 13 | class QueryResult; 14 | class TextQuery; 15 | 16 | class NotQuery :public Query_base 17 | { 18 | friend Query operator~(const Query&); 19 | //call Query's default copy constructor. 20 | NotQuery(const Query &q) :query(q){} 21 | string rep() const{ return "~(" + query.rep() + ")"; } 22 | QueryResult eval(const TextQuery&) const; 23 | 24 | Query query; 25 | }; 26 | 27 | inline Query operator~(const Query &operand) 28 | { 29 | return shared_ptr(new NotQuery(operand)); 30 | } 31 | 32 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_c/orquery.cpp: -------------------------------------------------------------------------------- 1 | #include"orquery.h" 2 | 3 | #include 4 | using std::make_shared; 5 | 6 | #include 7 | using std::set; 8 | 9 | #include"queryresult.h" 10 | #include"textquery.h" 11 | #include"query.h" 12 | 13 | QueryResult 14 | OrQuery::eval(const TextQuery &text) const 15 | { 16 | auto right = rhs.eval(text); 17 | auto left = lhs.eval(text); 18 | auto ret_lines = make_shared>(left.begin(), left.end()); 19 | ret_lines->insert(right.begin(), right.end()); 20 | return QueryResult(rep(), ret_lines, left.get_file()); 21 | } -------------------------------------------------------------------------------- /ch15/ex15.42_c/orquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _ORQUERY_H 2 | #define _ORQUERY_H 3 | 4 | #include 5 | using std::shared_ptr; 6 | 7 | #include"query.h" 8 | #include"binaryquery.h" 9 | 10 | class QueryResult; 11 | class TextQuery; 12 | 13 | class OrQuery :public BinaryQuery 14 | { 15 | friend Query operator|(const Query&, const Query&); 16 | OrQuery(const Query &left, const Query &right) :BinaryQuery(left, right, "|"){} 17 | QueryResult eval(const TextQuery&) const; 18 | }; 19 | 20 | inline Query operator|(const Query &lhs, const Query &rhs) 21 | { 22 | return shared_ptr(new OrQuery(lhs, rhs)); 23 | } 24 | 25 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_c/query.cpp: -------------------------------------------------------------------------------- 1 | #include"query.h" 2 | 3 | #include 4 | using std::ostream; 5 | 6 | ostream& 7 | operator<<(ostream &os, const Query &query) 8 | { 9 | return os << query.rep(); 10 | } -------------------------------------------------------------------------------- /ch15/ex15.42_c/query.h: -------------------------------------------------------------------------------- 1 | #ifndef _QUERY_H 2 | #define _QUERY_H 3 | 4 | #include 5 | using std::ostream; 6 | 7 | #include 8 | using std::shared_ptr; 9 | 10 | #include 11 | using std::string; 12 | 13 | #include"query_base.h" 14 | #include"queryresult.h" 15 | #include"wordquery.h" 16 | 17 | 18 | class TextQuery; 19 | 20 | class Query 21 | { 22 | friend Query operator~(const Query&); 23 | friend Query operator|(const Query&, const Query&); 24 | friend Query operator&(const Query&, const Query&); 25 | public: 26 | Query(const string&); 27 | //call QueryResult's default copy constructor. 28 | QueryResult eval(const TextQuery &t) const { return q->eval(t); } 29 | string rep() const { return q->rep(); } 30 | private: 31 | Query(shared_ptr query) :q(query){} 32 | shared_ptr q; 33 | }; 34 | 35 | ostream & operator<<(ostream &os, const Query &query); 36 | 37 | inline Query::Query(const string &s) :q(new WordQuery(s)){} 38 | 39 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_c/query_base.cpp: -------------------------------------------------------------------------------- 1 | #include"query_base.h" -------------------------------------------------------------------------------- /ch15/ex15.42_c/query_base.h: -------------------------------------------------------------------------------- 1 | #ifndef _QUERY_BASE_H 2 | #define _QUERY_BASE_H 3 | 4 | #include 5 | using std::string; 6 | 7 | #include"textquery.h" 8 | 9 | class Query_base 10 | { 11 | friend class Query; 12 | protected: 13 | using line_no = TextQuery::line_no; 14 | virtual ~Query_base() = default; 15 | private: 16 | virtual QueryResult eval(const TextQuery&) const = 0; 17 | virtual string rep() const = 0; 18 | }; 19 | 20 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_c/queryresult.cpp: -------------------------------------------------------------------------------- 1 | #include "queryresult.h" 2 | 3 | #include 4 | using std::ostream; 5 | 6 | ostream& 7 | print(ostream &os, const QueryResult &qr) 8 | { 9 | os <<"The result of your query "<< qr.sought <<" is: \n"; 10 | for (const auto &index: *qr.lines) 11 | os << "\t(line " << index + 1 << ")" 12 | << *(qr.file->begin() + index) << "\n"; 13 | return os; 14 | } 15 | 16 | /* 17 | Head is the first line of the range. 18 | Trail is the last line of the range. 19 | */ 20 | ostream& 21 | print(ostream& os, const QueryResult &qr,size_t head, size_t trail) 22 | { 23 | if (head > trail) 24 | { 25 | os << "illegal range!\n"; 26 | return os; 27 | } 28 | else 29 | { 30 | os << "The result of your query " << qr.sought << " is: \n"; 31 | for (const auto &index : *qr.lines) 32 | { 33 | if (index + 1 >= head&&index + 1 <= trail) 34 | { 35 | os << "\t(line " << index + 1 << ")" 36 | << *(qr.file->begin() + index) << "\n"; 37 | } 38 | } 39 | return os; 40 | } 41 | } -------------------------------------------------------------------------------- /ch15/ex15.42_c/test.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?" -------------------------------------------------------------------------------- /ch15/ex15.42_c/textquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _TEXTQUERY_H 2 | #define _TEXTQUERY_H 3 | 4 | #include 5 | using std::ifstream; 6 | 7 | #include 8 | using std::shared_ptr; 9 | 10 | #include 11 | using std::vector; 12 | 13 | #include 14 | using std::string; 15 | 16 | #include 17 | using std::map; 18 | 19 | #include 20 | using std::set; 21 | 22 | class QueryResult; 23 | 24 | class TextQuery 25 | { 26 | 27 | public: 28 | typedef vector::size_type line_no; 29 | 30 | TextQuery(ifstream&); 31 | QueryResult query(const string&) const; 32 | 33 | private: 34 | shared_ptr> file; 35 | map>> wm; 36 | 37 | shared_ptr> handlePunct(const string&); 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /ch15/ex15.42_c/wordquery.cpp: -------------------------------------------------------------------------------- 1 | #include"wordquery.h" -------------------------------------------------------------------------------- /ch15/ex15.42_c/wordquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _WORDQUERY_H 2 | #define _WORDQUERY_H 3 | 4 | #include 5 | using std::string; 6 | 7 | #include"query_base.h" 8 | #include"queryresult.h" 9 | #include"textquery.h" 10 | 11 | class WordQuery:public Query_base 12 | { 13 | friend class Query; 14 | WordQuery(const string &s) :query_word(s){} 15 | QueryResult eval(const TextQuery &t) const{ return t.query(query_word); } 16 | string rep() const { return query_word; } 17 | 18 | string query_word; 19 | }; 20 | 21 | 22 | #endif -------------------------------------------------------------------------------- /ch15/ex15_15_Bulk_quote.h: -------------------------------------------------------------------------------- 1 | /* 2 | ================================================================================= 3 | 4 | C++ Primer 5th Exercise Answer Source Code 5 | Copyright (C) 2014-2015 github.com/pezy/Cpp-Primer 6 | 7 | Disc_quote 8 | 9 | If you have questions, try to connect with me: pezy 10 | 11 | ================================================================================= 12 | */ 13 | 14 | #ifndef CP5_EX15_15_BULK_QUOTE_H_ 15 | #define CP5_EX15_15_BULK_QUOTE_H_ 16 | 17 | #include "ex15_15_Disc_quote.h" 18 | #include 19 | 20 | inline namespace EX15 { 21 | 22 | using std::string; 23 | 24 | class Bulk_quote : public Disc_quote { 25 | public: 26 | Bulk_quote() = default; 27 | Bulk_quote(string const& book, double price, size_t qty, double disc) : Disc_quote(book, price, qty, disc) { } 28 | virtual double net_price(std::size_t cnt) const override { 29 | if (cnt >= quantity) return cnt * (1 - discount) * price; 30 | else return cnt * price; 31 | } 32 | }; 33 | 34 | } 35 | 36 | #endif // CP5_EX15_15_BULK_QUOTE_H_ 37 | -------------------------------------------------------------------------------- /ch15/ex15_15_Disc_quote.h: -------------------------------------------------------------------------------- 1 | /* 2 | ================================================================================= 3 | 4 | C++ Primer 5th Exercise Answer Source Code 5 | Copyright (C) 2014-2015 github.com/pezy/Cpp-Primer 6 | 7 | Disc_quote 8 | 9 | If you have questions, try to connect with me: pezy 10 | 11 | ================================================================================= 12 | */ 13 | 14 | #ifndef CP5_EX15_15_DISC_QUOTE_H_ 15 | #define CP5_EX15_15_DISC_QUOTE_H_ 16 | 17 | #include "ex15_03_Quote.h" 18 | #include 19 | 20 | inline namespace EX15 { 21 | 22 | using std::string; 23 | 24 | class Disc_quote : public EX03::Quote { 25 | public: 26 | Disc_quote() = default; 27 | Disc_quote(string const& b, double p, size_t q, double d) : EX03::Quote(b, p), quantity(q), discount(d){ } 28 | virtual double net_price(size_t) const = 0; 29 | protected: 30 | size_t quantity = 0; 31 | double discount = 0.0; 32 | }; 33 | 34 | } 35 | 36 | #endif // CP5_EX15_15_DISC_QUOTE_H_ 37 | -------------------------------------------------------------------------------- /ch15/ex15_27_Bulk_quote.h: -------------------------------------------------------------------------------- 1 | /* 2 | ================================================================================= 3 | 4 | C++ Primer 5th Exercise Answer Source Code 5 | Copyright (C) 2014-2015 https://github.com/pezy/Cpp-Primer 6 | 7 | Bulk_quote 8 | inherited constructors from EX15::Disc_quote 9 | 10 | If you have questions, try to connect with me: pezy 11 | 12 | ================================================================================= 13 | */ 14 | 15 | #ifndef CP5_EX15_27_BULK_QUOTE_H 16 | #define CP5_EX15_27_BULK_QUOTE_H 17 | 18 | #include "ex15_15_Disc_quote.h" 19 | 20 | inline namespace EX27 { 21 | 22 | using std::string; 23 | 24 | class Bulk_quote : public Disc_quote { 25 | public: 26 | using Disc_quote::Disc_quote; 27 | virtual double net_price(std::size_t cnt) const override { 28 | if (cnt >= quantity) return cnt * (1 - discount) * price; 29 | else return cnt * price; 30 | } 31 | }; 32 | 33 | } 34 | 35 | #endif // CP5_EX15_27_BULK_QUOTE_H 36 | -------------------------------------------------------------------------------- /ch16/ex16.51.52/main.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file main.cpp 3 | * @author Alan.W 4 | * @date 12 Feb 2014 5 | * @remark This code is for the exercises from C++ Primer 5th Edition 6 | * @note 7 | ***************************************************************************/ 8 | //! 9 | //! Exercise 16.51: 10 | //! Determine what sizeof...(Args) and sizeof...(rest) return for each call to foo in this section. 11 | //! 12 | //! Exercise 16.52: 13 | //! Write a program to check your answer to the previous question. 14 | //! 15 | 16 | #include 17 | 18 | template 19 | void foo(T t,Args ...args) 20 | { 21 | std::cout << sizeof...(Args) << std::endl; 22 | std::cout << sizeof...(args) << std::endl; 23 | } 24 | 25 | 26 | int main() 27 | { 28 | foo(1,2); 29 | foo(1,23,4,5,6); 30 | } 31 | -------------------------------------------------------------------------------- /ch16/ex16_02_compare.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_EX16_02_COMPARE_H_ 2 | #define CP5_EX16_02_COMPARE_H_ 3 | 4 | #include 5 | 6 | template int compare(const T& v1, const T& v2) 7 | { 8 | if (std::less()(v1, v2)) { 9 | return -1; 10 | } 11 | 12 | if (std::less()(v2, v1)) { 13 | return 1; 14 | } 15 | 16 | return 0; 17 | } 18 | 19 | template 20 | int compare(const char (&s1)[N], const char (&s2)[M]) 21 | { 22 | return strcmp(s1, s2); 23 | } 24 | 25 | #endif // CP5_EX16_02_COMPARE_H_ 26 | -------------------------------------------------------------------------------- /ch16/ex16_04_find.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_EX16_04_FIND_H_ 2 | #define CP5_EX16_04_FIND_H_ 3 | 4 | template 5 | InputIt Find(InputIt begin, InputIt end, const T& value) 6 | { 7 | for (; begin != end; ++begin) { 8 | if (*begin == value) { 9 | return begin; 10 | } 11 | } 12 | return end; 13 | } 14 | 15 | #endif // CP5_EX16_04_FIND_H_ 16 | -------------------------------------------------------------------------------- /ch16/ex16_05_print_array.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_EX16_05_PRINT_ARRAY_H_ 2 | #define CP5_EX16_05_PRINT_ARRAY_H_ 3 | 4 | #include 5 | 6 | template void print_array(const T (&arr)[N]) 7 | { 8 | for (const auto& elem : arr) { 9 | std::cout << elem; 10 | } 11 | std::cout << std::endl; 12 | } 13 | 14 | #endif // CP5_EX16_05_PRINT_H_ 15 | -------------------------------------------------------------------------------- /ch16/ex16_06_begin_end.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_EX16_06_BEGIN_END_H_ 2 | #define CP5_EX16_06_BEGIN_END_H_ 3 | 4 | template T* Begin(T (&arr)[N]) 5 | { 6 | return arr; 7 | } 8 | 9 | template T* End(T (&arr)[N]) 10 | { 11 | return arr + N; 12 | } 13 | 14 | #endif // CP5_EX16_06_BEGIN_END_H_ 15 | -------------------------------------------------------------------------------- /ch16/ex16_07_sizeof_array.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_EX16_07_SIZEOF_ARRAY_H_ 2 | #define CP5_EX16_07_SIZEOF_ARRAY_H_ 3 | 4 | template 5 | constexpr unsigned SizeOfArray(const T (&arr)[N]) 6 | { 7 | return N; 8 | } 9 | 10 | #endif // CP5_EX16_07_SIZEOF_ARRAY_H_ 11 | -------------------------------------------------------------------------------- /ch16/ex16_12_blob_test.cpp: -------------------------------------------------------------------------------- 1 | #include "ex16_12_blob.h" 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | Blob sb1{"a", "b", "c"}; 8 | Blob sb2 = sb1; 9 | 10 | sb2[2] = "b"; 11 | 12 | if (sb1 > sb2) { 13 | for (auto iter = sb2.cbegin(); iter != sb2.cend(); ++iter) 14 | std::cout << *iter << " "; 15 | std::cout << std::endl; 16 | } 17 | 18 | ConstBlobPtr iter(sb2); 19 | std::cout << iter->size() << std::endl; 20 | } 21 | -------------------------------------------------------------------------------- /ch16/ex16_14_screen_test.cpp: -------------------------------------------------------------------------------- 1 | #include "ex16_14_screen.h" 2 | 3 | int main() 4 | { 5 | Screen<5, 5> screen('x'); 6 | screen.set(2, 2, 'o'); 7 | std::cout << screen << std::endl; 8 | 9 | std::cout << "please input some characters as you like:"; 10 | std::cin >> screen; 11 | std::cout << screen << std::endl; 12 | } 13 | -------------------------------------------------------------------------------- /ch16/ex16_19_print_container.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | std::ostream& print(const Container& c, std::ostream& os = std::cout) 6 | { 7 | using size_type = typename Container::size_type; 8 | for (size_type i = 0; i != c.size(); ++i) { 9 | os << c.at(i) << " "; 10 | } 11 | return os; 12 | } 13 | 14 | int main() 15 | { 16 | std::vector vec{2, 4, 6, 8, 7, 5, 3, 1}; 17 | print(vec) << "\n"; 18 | } -------------------------------------------------------------------------------- /ch16/ex16_20_print_container_iter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | std::ostream& print(const Container& c, std::ostream& os = std::cout) 6 | { 7 | for (auto iter = c.begin(); iter != c.end(); ++iter) { 8 | os << *iter << " "; 9 | } 10 | return os; 11 | } 12 | 13 | int main() 14 | { 15 | std::vector vec{2, 4, 6, 8, 7, 5, 3, 1}; 16 | print(vec) << "\n"; 17 | } -------------------------------------------------------------------------------- /ch16/ex16_21_debugdelete.cpp: -------------------------------------------------------------------------------- 1 | #include "ex16_21_debugdelete.h" 2 | #include 3 | #include 4 | 5 | using std::string; 6 | 7 | int main() 8 | { 9 | double* p = new double(8.0); 10 | DebugDelete d; 11 | d(p); 12 | 13 | int* ip = new int; 14 | DebugDelete()(ip); 15 | 16 | std::unique_ptr up(new int, DebugDelete()); 17 | std::unique_ptr usp(new string, DebugDelete()); 18 | } -------------------------------------------------------------------------------- /ch16/ex16_21_debugdelete.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_EX16_21_DEBUGDELETE_H_ 2 | #define CP5_EX16_21_DEBUGDELETE_H_ 3 | 4 | #include 5 | 6 | class DebugDelete { 7 | public: 8 | DebugDelete(std::ostream& os = std::cerr) : os_(os) {} 9 | 10 | template void operator()(T* p) const 11 | { 12 | os_ << "deleting unique_ptr by '" << __PRETTY_FUNCTION__ << "'\n"; 13 | delete p; 14 | } 15 | 16 | private: 17 | std::ostream& os_; 18 | }; 19 | 20 | #endif // CP5_EX16_21_DEBUGDELETE_H_ -------------------------------------------------------------------------------- /ch16/ex16_22_textquery_test.cpp: -------------------------------------------------------------------------------- 1 | #include "ex16_22_textquery.h" 2 | #include 3 | 4 | void runQueries(std::ifstream& infile) 5 | { 6 | TextQuery tq(infile); 7 | while (true) { 8 | std::cout << "enter word to look for, or q to quit: "; 9 | string s; 10 | if (!(std::cin >> s) || s == "q") break; 11 | print(std::cout, tq.query(s)) << std::endl; 12 | } 13 | } 14 | 15 | int main() 16 | { 17 | std::ifstream file("../data/storyDataFile.txt"); 18 | runQueries(file); 19 | } 20 | -------------------------------------------------------------------------------- /ch16/ex16_24_blob_test.cpp: -------------------------------------------------------------------------------- 1 | #include "ex16_24_blob.h" 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | Blob sb1{"a", "b", "c"}; 8 | Blob sb2 = sb1; 9 | 10 | sb2[2] = "b"; 11 | 12 | if (sb1 > sb2) { 13 | for (auto iter = sb2.cbegin(); iter != sb2.cend(); ++iter) { 14 | std::cout << *iter << " "; 15 | } 16 | std::cout << std::endl; 17 | } 18 | 19 | ConstBlobPtr iter(sb2); 20 | std::cout << iter->size() << std::endl; 21 | 22 | std::vector vec{"good", "for", "you"}; 23 | Blob sb3(vec.begin(), vec.end()); 24 | 25 | for (auto&& s : sb3) { 26 | std::cout << s << " "; 27 | } 28 | std::cout << "\n"; 29 | } 30 | -------------------------------------------------------------------------------- /ch16/ex16_29_blob_test.cpp: -------------------------------------------------------------------------------- 1 | #include "ex16_24_blob.h" 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | Blob sb1{"a", "b", "c"}; 8 | Blob sb2 = sb1; 9 | 10 | sb2[2] = "b"; 11 | 12 | if (sb1 > sb2) { 13 | for (auto iter = sb2.cbegin(); iter != sb2.cend(); ++iter) { 14 | std::cout << *iter << " "; 15 | } 16 | std::cout << std::endl; 17 | } 18 | 19 | ConstBlobPtr iter(sb2); 20 | std::cout << iter->size() << std::endl; 21 | 22 | std::vector vec{"good", "for", "you"}; 23 | Blob sb3(vec.begin(), vec.end()); 24 | 25 | for (auto&& s : sb3) { 26 | std::cout << s << " "; 27 | } 28 | std::cout << "\n"; 29 | } 30 | -------------------------------------------------------------------------------- /ch16/ex16_47_flip.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void f(int v1, int& v2) 4 | { 5 | std::cout << v1 << " " << ++v2 << std::endl; 6 | } 7 | 8 | void g(int&& i, int& j) 9 | { 10 | std::cout << i << " " << ++j << std::endl; 11 | } 12 | 13 | template 14 | void flip(F f, T1&& t1, T2&& t2) 15 | { 16 | f(std::forward(t2), std::forward(t1)); 17 | } 18 | 19 | int main() 20 | { 21 | int j = 0; 22 | flip(f, j, 42); 23 | flip(g, j, 42); 24 | } -------------------------------------------------------------------------------- /ch16/ex16_50_overload_template.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::cout; 3 | using std::endl; 4 | 5 | template void f(T) 6 | { 7 | cout << "template 1\n"; 8 | } 9 | 10 | template void f(const T *) 11 | { 12 | cout << "template 2\n"; 13 | } 14 | 15 | template void g(T) 16 | { 17 | cout << "template 3\n"; 18 | } 19 | 20 | template void g(T*) 21 | { 22 | cout << "template 4\n"; 23 | } 24 | 25 | 26 | int main() 27 | { 28 | int i = 42, *p = &i; 29 | const int ci = 0, *p2 = &ci; 30 | g(42); 31 | g(p); 32 | g(ci); 33 | g(p2); 34 | f(42); 35 | f(p); 36 | f(ci); 37 | f(p2); 38 | } 39 | -------------------------------------------------------------------------------- /ch16/ex16_52_variadic_template.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::string; 5 | using std::cout; 6 | using std::endl; 7 | 8 | template 9 | void foo(const T & t, const Args& ... rest) 10 | { 11 | cout << "sizeof...(Args): " << sizeof...(Args) << endl; 12 | cout << "sizeof...(rest): " << sizeof...(rest) << endl; 13 | } 14 | 15 | int main() 16 | { 17 | int i = 0; 18 | double d = 3.14; 19 | string s = "how now brown cow"; 20 | cout << "foo(i, s, 42, d) : " << endl; 21 | foo(i, s, 42, d); 22 | cout << "foo(s, 42, \"hi\") : " << endl; 23 | foo(s, 42, "hi"); 24 | cout << "foo(d, s) : " << endl; 25 | foo(d, s); 26 | cout << "foo(\"hi\") : " << endl; 27 | foo("hi"); 28 | } 29 | -------------------------------------------------------------------------------- /ch17/ex17.21/data/record.txt: -------------------------------------------------------------------------------- 1 | green (9998886666 9996668888 2 | morgan 2015552368 8625550123 3 | drew 9735550130 4 | lee 6095550132 2015550175 8005550000 5 | -------------------------------------------------------------------------------- /ch17/ex17_03_text_query.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using std::string; 13 | using std::vector; 14 | using std::tuple; 15 | using std::shared_ptr; 16 | using std::set; 17 | using std::map; 18 | using std::ifstream; 19 | using std::ostream; 20 | 21 | namespace EX03 { 22 | using line_no = vector::size_type; 23 | using query_result = 24 | tuple>, shared_ptr>>; 25 | 26 | class TextQuery { 27 | public: 28 | // read the input file and build the map of lines to line numbers. 29 | TextQuery(ifstream&); 30 | query_result query(const string&) const; 31 | 32 | private: 33 | shared_ptr> file; // input file 34 | // map of each word to the set of the lines in which that word appears. 35 | map>> wm; 36 | }; 37 | 38 | ostream& print(ostream&, const query_result&); 39 | } // namespace EX03 -------------------------------------------------------------------------------- /ch17/ex17_03_text_query_test.cpp: -------------------------------------------------------------------------------- 1 | #include "ex17_03_text_query.h" 2 | 3 | void runQueries(ifstream& infile) 4 | { 5 | EX03::TextQuery tq(infile); 6 | while (true) { 7 | std::cout << "Enter word to look for, or q to quit: "; 8 | string s; 9 | if (!(std::cin >> s) || s == "q") break; 10 | EX03::print(std::cout, tq.query(s)) << std::endl; 11 | } 12 | } 13 | 14 | int main() 15 | { 16 | ifstream file("../data/storyDataFile.txt"); 17 | runQueries(file); 18 | } -------------------------------------------------------------------------------- /ch17/ex17_10.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | // init from the sequence: 1, 2, 3, 5, 8, 13, 21 8 | std::bitset<22> bitseq("1000000010000100101110"); 9 | std::cout << bitseq << std::endl; 10 | 11 | // Default initialize, then turn on. 12 | std::bitset<22> bit_default; 13 | for (auto i : {1, 2, 3, 5, 8, 13, 21}) 14 | bit_default.set(i); 15 | std::cout << bit_default << std::endl; 16 | 17 | assert(bitseq == bit_default); 18 | } -------------------------------------------------------------------------------- /ch17/ex17_11_quiz_responses.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace EX11 { 7 | using size = std::size_t; 8 | template class QuizResponses { 9 | public: 10 | QuizResponses() = default; 11 | QuizResponses(const std::string& s) : answers(s) {} 12 | 13 | // added a function that takes a question number and a value to indicate 14 | // a true/false answer and updates the quiz results accordingly 15 | void answer(size n, bool v) { answers.set(n - 1, v); } 16 | 17 | // generate grades on the quiz 18 | size score(const QuizResponses& correct) 19 | { 20 | return (this->answers ^ correct.answers).flip().count() * 1.0 / N * 100; 21 | } 22 | 23 | private: 24 | std::bitset answers; 25 | }; 26 | } // namespace EX11 27 | -------------------------------------------------------------------------------- /ch17/ex17_11_quiz_responses_test.cpp: -------------------------------------------------------------------------------- 1 | #include "ex17_11_quiz_responses.h" 2 | #include 3 | 4 | int main() 5 | { 6 | EX11::QuizResponses<10> simple_quiz_answers("1100110101"); 7 | 8 | EX11::QuizResponses<100> complicated_quiz_answers; 9 | complicated_quiz_answers.answer(1, true); 10 | complicated_quiz_answers.answer(2, false); 11 | complicated_quiz_answers.answer(3, true); 12 | 13 | EX11::QuizResponses<10> simple_quiz_correct("1010101010"); 14 | std::cout << simple_quiz_answers.score(simple_quiz_correct) << std::endl; 15 | } -------------------------------------------------------------------------------- /ch17/ex17_14.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using std::regex; 7 | 8 | int main() 9 | { 10 | try { 11 | regex r("[[:alnum]+\\.(cpp|cxx|cc)$", regex::icase); 12 | } 13 | catch (std::regex_error e) { 14 | std::cout << e.what() << "\ncode:" << e.code() << std::endl; 15 | } 16 | } 17 | 18 | // output 19 | // Unexpected end of character class. 20 | // code:1 -------------------------------------------------------------------------------- /ch18/README.md: -------------------------------------------------------------------------------- 1 | # Chapter 18. Tools for Large Programs 2 | 3 | ## Exercise 18.1 4 | 5 | > What is the type of the exception object in the following throws? 6 | > 7 | > **(a)**`range_error r("error");` 8 | > `throw r`; 9 | > **(b)**`exception *p = &r;` 10 | > `throw *P;` 11 | > 12 | > What would happen if the `throw` in **(b)** were written as `throw p`? 13 | 14 | The type of the exception object in (a) is range_error which is used to report range errors in internal computations. 15 | The type of the exception object in (b) is exception. 16 | If the "throw" in (b) were written as "throw p", there will be a runtime error. 17 | 18 | ## Exercise 18.2 19 | 20 | > Explain what happens if an exception occurs at the indicated point: 21 | 22 | ```cpp 23 | void exercise(int *b, int *e) 24 | { 25 | vector v(b,e); 26 | int *p = new int[v.size()]; 27 | ifstream in("ints"); 28 | // exception occurs here 29 | } 30 | ``` 31 | 32 | The space "p" points will not be free. There will be a memory leak. 33 | 34 | ## Exercise 18.3 35 | -------------------------------------------------------------------------------- /data/book.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 6 | -------------------------------------------------------------------------------- /data/even.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 4 3 | 6 4 | 8 5 | -------------------------------------------------------------------------------- /data/given_to_transform.txt: -------------------------------------------------------------------------------- 1 | where r u 2 | y dont u send me a pic 3 | k thk l8r -------------------------------------------------------------------------------- /data/input.txt: -------------------------------------------------------------------------------- 1 | 1 2 3 4 5 6 7 8 9 2 | -------------------------------------------------------------------------------- /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/odd.txt: -------------------------------------------------------------------------------- 1 | 1 3 5 7 9 -------------------------------------------------------------------------------- /data/phonenumbers.txt: -------------------------------------------------------------------------------- 1 | morgan 2015552368 8625550123 2 | drew 9735550130 3 | lee 6095550132 2015550175 8005550000 -------------------------------------------------------------------------------- /data/store1: -------------------------------------------------------------------------------- 1 | 0-201-70353-X 4 24.99 2 | 0-201-82470-1 4 45.39 3 | 0-201-88954-4 2 15.00 4 | 0-201-88954-4 5 12.00 5 | 0-201-88954-4 7 12.00 6 | 0-201-88954-4 2 12.00 7 | 0-399-82477-1 2 45.39 8 | 0-399-82477-1 3 45.39 9 | 0-201-78345-X 3 20.00 10 | 0-201-78345-X 2 25.00 11 | -------------------------------------------------------------------------------- /data/store2: -------------------------------------------------------------------------------- 1 | 0-201-78345-X 3 20.00 2 | 0-201-78345-X 2 25.00 3 | 0-999-78345-X 3 20.00 4 | 0-201-78345-X 2 25.00 5 | 0-201-78345-X 3 20.00 6 | 0-201-78345-X 2 25.00 7 | 0-999-78345-X 3 20.00 8 | 0-201-78345-X 2 25.00 9 | -------------------------------------------------------------------------------- /data/store3: -------------------------------------------------------------------------------- 1 | 0-201-70353-X 4 24.99 2 | 0-201-82470-1 4 45.39 3 | 0-201-88954-4 2 15.00 4 | 0-201-88954-4 5 12.00 5 | 0-201-88954-4 7 12.00 6 | 0-201-88954-4 2 12.00 7 | 0-399-82477-1 2 45.39 8 | 0-399-82477-1 3 45.39 9 | 0-201-78345-X 3 20.00 10 | 0-201-78345-X 2 25.00 11 | -------------------------------------------------------------------------------- /data/store4: -------------------------------------------------------------------------------- 1 | 0-201-70353-X 4 24.99 2 | 0-201-82470-1 4 45.39 3 | 0-201-88954-4 2 15.00 4 | 0-201-88954-4 5 12.00 5 | 0-201-88954-4 7 12.00 6 | 0-201-88954-4 2 12.00 7 | 0-399-82477-1 2 45.39 8 | 0-399-82477-1 3 45.39 9 | 0-201-78345-X 3 20.00 10 | 0-201-78345-X 2 25.00 11 | -------------------------------------------------------------------------------- /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?" 11 | -------------------------------------------------------------------------------- /data/word_transformation.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 -------------------------------------------------------------------------------- /data/word_transformation_bad.txt: -------------------------------------------------------------------------------- 1 | l8r -------------------------------------------------------------------------------- /generate_format_command.py: -------------------------------------------------------------------------------- 1 | from sys import argv 2 | from os import listdir 3 | from os.path import isfile, join 4 | 5 | if len(argv) > 1: 6 | mypath = argv[1] 7 | else: 8 | mypath = '.' 9 | 10 | print 'clang-format -i', 11 | 12 | onlyfiles = [ f for f in listdir(mypath) if isfile(join(mypath, f)) ] 13 | for file in onlyfiles: 14 | if (file.endswith(('.cpp', '.cc', '.h'))): 15 | print mypath + '\\' + file, 16 | --------------------------------------------------------------------------------