├── .gitignore ├── Chapter_18 └── README.md ├── Chapter_10 └── README.md ├── Chapter_08 └── README.md ├── Chapter_09 └── README.md ├── Chapter_11 └── README.md ├── Chapter_12 └── README.md ├── Chapter_13 └── README.md ├── Chapter_14 └── README.md ├── Chapter_15 └── README.md ├── Chapter_16 └── README.md ├── Chapter_17 └── README.md ├── Chapter_01 ├── exercise_01.cpp ├── exercise_03.cpp ├── exercise_02.cpp ├── exercise_13b.cpp ├── exercise_09.cpp ├── exercise_13a.cpp ├── exercise_10.cpp ├── exercise_16.cpp ├── exercise_04.cpp ├── exercise_22.cpp ├── exercise_21.cpp ├── exercise_20.cpp ├── exercise_13c.cpp ├── exercise_05.cpp ├── exercise_22b.cpp ├── exercise_11.cpp ├── exercise_21b.cpp ├── exercise_18.cpp ├── exercise_23.cpp ├── exercise_19.cpp ├── CMakeLists.txt └── exercise_25.cpp ├── data ├── books.txt └── lorem_ipsum.txt ├── include ├── Sales_data.hpp ├── Chapter6.hpp ├── exexercise_31.hpp ├── Person.hpp ├── Person_v2.hpp ├── Sales_data_v2.hpp ├── Screen.hpp ├── Person_v3.hpp ├── Screen_v2.hpp ├── Person_v5.hpp ├── Person_v4.hpp ├── Sales_data_v3.hpp ├── Screen_v4.hpp ├── Screen_v3.hpp ├── Sales_data_v4.hpp ├── Sales_data_v5.hpp ├── Sales_data_v6.hpp ├── Sales_data_v7.hpp ├── Sales_data_v8.hpp ├── Screen_v5.hpp └── Screen_v6.hpp ├── Chapter_04 ├── CMakeLists.txt ├── exercise_04.cpp ├── exercise_06.cpp ├── exercise_21.cpp ├── exercise_22a.cpp ├── exercise_31.cpp ├── exercise_22b.cpp └── exercise_28.cpp ├── Chapter_02 ├── exercise_08.cpp ├── exercise_40.cpp ├── CMakeLists.txt ├── exercise_04.cpp ├── exercise_18.cpp ├── exercise_34.cpp ├── exercise_42a.cpp ├── exercise_42d.cpp ├── exercise_42c.cpp ├── exercise_41a.cpp ├── exercise_42b.cpp ├── exercise_41d.cpp ├── exercise_41c.cpp ├── exercise_41b.cpp ├── exercise_42f.cpp └── exercise_41f.cpp ├── Chapter_07 ├── CMakeLists.txt ├── exercise_27.cpp ├── exercise_29.cpp ├── exercise_13.cpp ├── exercise_11.cpp ├── exercise_07.cpp ├── exercise_02.cpp ├── exercise_03.cpp └── exercise_01.cpp ├── Chapter_03 ├── exercise_01b.cpp ├── exercise_02b.cpp ├── exercise_14.cpp ├── exercise_15.cpp ├── exercise_02a.cpp ├── exercise_01a.cpp ├── exercise_41.cpp ├── exercise_31.cpp ├── exercise_32b.cpp ├── exercise_01c.cpp ├── exercise_35.cpp ├── exercise_36b.cpp ├── exercise_06.cpp ├── exercise_25.cpp ├── exercise_32a.cpp ├── exercise_39a.cpp ├── exercise_39b.cpp ├── exercise_40.cpp ├── exercise_05a.cpp ├── exercise_42.cpp ├── exercise_05b.cpp ├── exercise_10.cpp ├── exercise_08b.cpp ├── exercise_08a.cpp ├── exercise_23.cpp ├── exercise_24a.cpp ├── exercise_07.cpp ├── exercise_45a.cpp ├── exercise_36a.cpp ├── exercise_45b.cpp ├── exercise_45c.cpp ├── exercise_24b.cpp ├── exercise_44a.cpp ├── exercise_04a.cpp ├── exercise_20a.cpp ├── exercise_44b.cpp ├── exercise_04b.cpp ├── exercise_17.cpp ├── exercise_43a.cpp ├── exercise_43b.cpp ├── exercise_22.cpp ├── exercise_43c.cpp ├── exercise_44c.cpp ├── exercise_20b.cpp ├── exercise_01d.cpp ├── exercise_01g.cpp ├── exercise_01f.cpp ├── CMakeLists.txt ├── exercise_01e.cpp ├── exercise_01h.cpp └── exercise_16.cpp ├── Chapter_06 ├── exercise_11.cpp ├── exercise_07.cpp ├── fact.cpp ├── exercise_25.cpp ├── exercise_21.cpp ├── exercise_27.cpp ├── exercise_33.cpp ├── factMain.cpp ├── exercise_05.cpp ├── exercise_34.cpp ├── exercise_26.cpp ├── exercise_04.cpp ├── exercise_51.cpp ├── exercise_17b.cpp ├── exercise_10.cpp ├── exercise_22.cpp ├── exercise_12.cpp ├── exercise_17a.cpp ├── exercise_55.cpp ├── exercise_47.cpp ├── CMakeLists.txt ├── exercise_42.cpp ├── exercise_37.cpp ├── exercise_23.cpp └── exercise_03.cpp ├── CMakeLists.txt └── Chapter_05 ├── exercise_23.cpp ├── exercise_06.cpp ├── CMakeLists.txt ├── exercise_16b.cpp ├── exercise_03.cpp ├── exercise_24.cpp ├── exercise_16d.cpp ├── exercise_05.cpp ├── exercise_16a.cpp ├── exercise_17.cpp ├── exercise_16c.cpp ├── exercise_20.cpp ├── exercise_09.cpp ├── exercise_25.cpp ├── exercise_14.cpp ├── exercise_21.cpp ├── exercise_10a.cpp ├── exercise_10b.cpp ├── exercise_11.cpp └── exercise_12.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore swap files 2 | *~ 3 | 4 | # Ignore bak files 5 | .bak 6 | .backup 7 | 8 | # Ignore build folder 9 | build 10 | -------------------------------------------------------------------------------- /Chapter_18/README.md: -------------------------------------------------------------------------------- 1 | #Chapter Eighteen Answers 2 | 3 | --- 4 | [☚ Chapter 17](../Chapter_17) Chapter 18
5 | [Home](https://github.com/adobrich/CppPrimer) 6 | -------------------------------------------------------------------------------- /Chapter_10/README.md: -------------------------------------------------------------------------------- 1 | #Chapter Ten Answers 2 | 3 | --- 4 | [☚ Chapter 09](../Chapter_09) Chapter 10 [Chapter 11 ☛](../Chapter_11)
5 | [Home](https://github.com/adobrich/CppPrimer) 6 | -------------------------------------------------------------------------------- /Chapter_08/README.md: -------------------------------------------------------------------------------- 1 | #Chapter Eight Answers 2 | 3 | --- 4 | [☚ Chapter 07](../Chapter_07) Chapter 08 [Chapter 09 ☛](../Chapter_09)
5 | [Home](https://github.com/adobrich/CppPrimer) 6 | -------------------------------------------------------------------------------- /Chapter_09/README.md: -------------------------------------------------------------------------------- 1 | #Chapter Nine Answers 2 | 3 | --- 4 | [☚ Chapter 08](../Chapter_08) Chapter 09 [Chapter 10 ☛](../Chapter_10)
5 | [Home](https://github.com/adobrich/CppPrimer) 6 | -------------------------------------------------------------------------------- /Chapter_11/README.md: -------------------------------------------------------------------------------- 1 | #Chapter Eleven Answers 2 | 3 | --- 4 | [☚ Chapter 10](../Chapter_10) Chapter 11 [Chapter 12 ☛](../Chapter_12)
5 | [Home](https://github.com/adobrich/CppPrimer) 6 | -------------------------------------------------------------------------------- /Chapter_12/README.md: -------------------------------------------------------------------------------- 1 | #Chapter Twelve Answers 2 | 3 | --- 4 | [☚ Chapter 11](../Chapter_11) Chapter 12 [Chapter 13 ☛](../Chapter_13)
5 | [Home](https://github.com/adobrich/CppPrimer) 6 | -------------------------------------------------------------------------------- /Chapter_13/README.md: -------------------------------------------------------------------------------- 1 | #Chapter Thirteen Answers 2 | 3 | --- 4 | [☚ Chapter 12](../Chapter_12) Chapter 13 [Chapter 14 ☛](../Chapter_14)
5 | [Home](https://github.com/adobrich/CppPrimer) 6 | -------------------------------------------------------------------------------- /Chapter_14/README.md: -------------------------------------------------------------------------------- 1 | #Chapter Fourteen Answers 2 | 3 | --- 4 | [☚ Chapter 13](../Chapter_13) Chapter 14 [Chapter 15 ☛](../Chapter_15)
5 | [Home](https://github.com/adobrich/CppPrimer) 6 | -------------------------------------------------------------------------------- /Chapter_15/README.md: -------------------------------------------------------------------------------- 1 | #Chapter Fifteen Answers 2 | 3 | --- 4 | [☚ Chapter 14](../Chapter_14) Chapter 15 [Chapter 16 ☛](../Chapter_16)
5 | [Home](https://github.com/adobrich/CppPrimer) 6 | -------------------------------------------------------------------------------- /Chapter_16/README.md: -------------------------------------------------------------------------------- 1 | #Chapter Sixteen Answers 2 | 3 | --- 4 | [☚ Chapter 15](../Chapter_15) Chapter 16 [Chapter 17 ☛](../Chapter_17)
5 | [Home](https://github.com/adobrich/CppPrimer) 6 | -------------------------------------------------------------------------------- /Chapter_17/README.md: -------------------------------------------------------------------------------- 1 | #Chapter Seventeen Answers 2 | 3 | --- 4 | [☚ Chapter 16](../Chapter_16) Chapter 17 [Chapter 18 ☛](../Chapter_18)
5 | [Home](https://github.com/adobrich/CppPrimer) 6 | -------------------------------------------------------------------------------- /Chapter_01/exercise_01.cpp: -------------------------------------------------------------------------------- 1 | // Review the documentation for your compiler and determine what file 2 | // naming convention it uses. Compile and run the main program from 3 | // page 2 4 | 5 | int main() 6 | { 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /data/books.txt: -------------------------------------------------------------------------------- 1 | 0-006-47988-X 1 12.95 2 | 0-006-47988-X 1 12.95 3 | 0-006-47988-X 1 12.95 4 | 0-007-46582-3 4 22.45 5 | 0-006-48612-6 3 19.0 6 | 0-007-48384-8 7 32.50 7 | 0-007-11955-0 2 10.0 8 | 0-002-24739-9 1 50.0 9 | 10 | -------------------------------------------------------------------------------- /Chapter_01/exercise_03.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to print 'Hello, World.' on the standard output. 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | std::cout << "Hello, World." << std::endl; 8 | 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /Chapter_01/exercise_02.cpp: -------------------------------------------------------------------------------- 1 | // Change the program to return -1. A return value of -1 is often 2 | // treated as an indicator that the program failed. Recompile and rerun 3 | // your program to see how your system treats a failure indicator from main. 4 | 5 | int main() 6 | { 7 | return -1; 8 | } 9 | -------------------------------------------------------------------------------- /include/Sales_data.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SALES_DATA_HPP 2 | #define SALES_DATA_HPP 3 | 4 | #include 5 | 6 | struct Sales_data 7 | { 8 | std::string bookNo; 9 | unsigned units_sold = 0; 10 | double price = 0.0; 11 | double revenue = 0.0; 12 | 13 | }; // Sales_data class 14 | 15 | #endif // SALES_DATA_HPP 16 | -------------------------------------------------------------------------------- /Chapter_01/exercise_13b.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the exercises from 1.4.1 (p. 13) using for loops. 2 | // Exercise 1.10 rewritten using a for loop. 3 | 4 | #include 5 | 6 | int main() 7 | { 8 | for (int i = 10; i >= 0; --i) 9 | { 10 | std::cout << i << std::endl; 11 | } 12 | 13 | return 0; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Chapter_04/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(exercise_04 exercise_04.cpp) 2 | add_executable(exercise_06 exercise_06.cpp) 3 | add_executable(exercise_21 exercise_21.cpp) 4 | add_executable(exercise_22a exercise_22a.cpp) 5 | add_executable(exercise_22b exercise_22b.cpp) 6 | add_executable(exercise_28 exercise_28.cpp) 7 | add_executable(exercise_31 exercise_31.cpp) 8 | -------------------------------------------------------------------------------- /Chapter_02/exercise_08.cpp: -------------------------------------------------------------------------------- 1 | // Using escape sequences, write a program to print 2M followed by a new line. 2 | // Modify the program to print 2, then a tab, then an M, followed by a new 3 | // line. 4 | 5 | #include 6 | 7 | int main() 8 | { 9 | std::cout << "\062\115\012"; 10 | std::cout << "\062\t\115\012"; 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /include/Chapter6.hpp: -------------------------------------------------------------------------------- 1 | // Write a header file named `Chapter6.h` (I prefer .hpp) that contains 2 | // declarations for the functions you wrote for the exercises in 3 | // § 6.1 (p. 205). 4 | 5 | #ifndef CHAPTER6_HPP 6 | #define CHAPTER6_HPP 7 | 8 | int fact(int n); 9 | 10 | void test(); 11 | 12 | int getFactorial(); 13 | 14 | int getAbsolute(int x); 15 | 16 | #endif // CHAPTER6_HPP 17 | -------------------------------------------------------------------------------- /Chapter_07/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(exercise_01 exercise_01.cpp) 2 | add_executable(exercise_02 exercise_02.cpp) 3 | add_executable(exercise_03 exercise_03.cpp) 4 | add_executable(exercise_07 exercise_07.cpp) 5 | add_executable(exercise_11 exercise_11.cpp) 6 | add_executable(exercise_13 exercise_13.cpp) 7 | add_executable(exercise_27 exercise_27.cpp) 8 | add_executable(exercise_29 exercise_29.cpp) 9 | 10 | -------------------------------------------------------------------------------- /include/exexercise_31.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EXERCISE_31_HPP 2 | #define EXERCISE_31_HPP 3 | 4 | // Forward declaration 5 | class Y; 6 | 7 | class X 8 | { 9 | public: 10 | X() = default; 11 | 12 | private: 13 | Y* why = nullptr; 14 | }; // end X class 15 | 16 | class Y 17 | { 18 | public: 19 | Y() = default; 20 | 21 | private: 22 | X ex = X(); 23 | }; // end Y class 24 | 25 | #endif // EXERCISE_31_HPP 26 | 27 | -------------------------------------------------------------------------------- /Chapter_03/exercise_01b.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the exercises from § 1.4.1 (p. 13) and § 2.6.2 (p. 76) 2 | // with appropriate using declarations. 3 | 4 | // Rewrite of exercise 1.10 5 | 6 | #include 7 | 8 | using std::cout; 9 | using std::endl; 10 | 11 | int main() 12 | { 13 | int v1 = 10; 14 | while ( v1 >= 0) 15 | { 16 | cout << v1 << endl; 17 | --v1; 18 | } 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Chapter_01/exercise_09.cpp: -------------------------------------------------------------------------------- 1 | // Write a program that uses a while to sum the numbers 2 | // from 50 to 100 3 | 4 | #include 5 | 6 | int main() 7 | { 8 | int sum = 0; 9 | int val = 50; 10 | while (val <= 100) 11 | { 12 | sum += val; 13 | ++val; 14 | } 15 | std::cout << "The sum of the numbers from 50 to 100 inclusive is: " 16 | << sum << std::endl; 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter_01/exercise_13a.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the exercises from 1.4.1 (p. 13) using for loops. 2 | // Exercise 1.09 rewritten using a for loop. 3 | 4 | #include 5 | 6 | int main () 7 | { 8 | int sum = 0; 9 | for (int i = 50; i <= 100; ++i) 10 | { 11 | sum += i; 12 | } 13 | std::cout << "The sum of the numbers from 50 to 100 inclusive is: " 14 | << sum << std::endl; 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /include/Person.hpp: -------------------------------------------------------------------------------- 1 | // Write a class named Person that represents the name and address of a person. 2 | // Use a string to hold each of these elements. Subsequent exercises will 3 | // incrementally add features to this class. 4 | 5 | #ifndef PERSON_HPP 6 | #define PERSON_HPP 7 | 8 | #include 9 | 10 | struct Person 11 | { 12 | std::string name; 13 | std::string address; 14 | }; // Person Class 15 | 16 | #endif // PERSON_HPP 17 | -------------------------------------------------------------------------------- /Chapter_01/exercise_10.cpp: -------------------------------------------------------------------------------- 1 | // In addition to the '++' operator that adds 1 to its operand, there is a 2 | // decrement operator '--' that subtracts 1. Use the decrement operator 3 | // to write a while that prints the numbers from ten down to zero. 4 | 5 | #include 6 | 7 | int main() 8 | { 9 | int v1 = 10; 10 | while ( v1 >= 0) 11 | { 12 | std::cout << v1 << std::endl; 13 | --v1; 14 | } 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter_01/exercise_16.cpp: -------------------------------------------------------------------------------- 1 | // Write your own version of a program that prints the sum of a set of 2 | // integers read from cin. 3 | 4 | #include 5 | 6 | int main() 7 | { 8 | int sum = 0; 9 | std::cout << "Enter some numbers to be added: "; 10 | int userInput = 0; 11 | while (std::cin >> userInput) 12 | { 13 | sum += userInput; 14 | } 15 | std::cout << "Total = " << sum << std::endl; 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter_03/exercise_02b.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to read the standard input a line at a time. 2 | // Modify your program to read a word at a time 3 | 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::cin; 9 | using std::endl; 10 | using std::string; 11 | 12 | int main() 13 | { 14 | string userInput; 15 | while (cin >> userInput) 16 | { 17 | cout << userInput << endl; 18 | } 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Chapter_07/exercise_27.cpp: -------------------------------------------------------------------------------- 1 | // Add the move, set, and display operations to your version of Screen. 2 | // Test your class by executing the following code: 3 | 4 | #include 5 | #include "../include/Screen_v3.hpp" 6 | 7 | using std::cout; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | Screen myScreen(5, 5, 'X'); 13 | myScreen.move(4,0).set('#').display(cout); 14 | cout << "\n"; 15 | myScreen.display(cout); 16 | cout << "\n"; 17 | 18 | return 0; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /Chapter_07/exercise_29.cpp: -------------------------------------------------------------------------------- 1 | // Revise your Screen class so that move, set and display functions return 2 | // Screen and check your prediction from the previous exercise. 3 | #include 4 | 5 | #include "../include/Screen_v4.hpp" 6 | 7 | int main() 8 | { 9 | Screen my_screen(5, 5, 'X'); 10 | my_screen.move(4, 0).set('#').display(std::cout); 11 | std::cout << std::endl; 12 | my_screen.display(std::cout); 13 | std::cout << std::endl; 14 | 15 | return 0; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /Chapter_06/exercise_11.cpp: -------------------------------------------------------------------------------- 1 | // Write and test your own version of `reset` that takes a reference. 2 | 3 | #include 4 | 5 | using std::cout; 6 | using std::endl; 7 | 8 | void reset(int& x) 9 | { 10 | x = 0; 11 | } 12 | 13 | int main() 14 | { 15 | int testValue = 42; 16 | cout << "Value is: \t" << testValue << endl; 17 | reset(testValue); 18 | cout << "Value has been reset." << endl; 19 | cout << "New value is: \t" << testValue << endl; 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Chapter_03/exercise_14.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to read a sequence of ints from cin and store 2 | // those values in a vector. 3 | 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::cin; 9 | using std::vector; 10 | 11 | int main() 12 | { 13 | cout << "Enter some numbers: "; 14 | int userInput; 15 | vector collectedData; 16 | while (cin >> userInput) 17 | { 18 | collectedData.push_back(userInput); 19 | } 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Chapter_01/exercise_04.cpp: -------------------------------------------------------------------------------- 1 | // Our program used the addition operator '+' to add two numbers. Write 2 | // a program that uses the multiplication operator '*' to print the 3 | // product instead. 4 | 5 | #include 6 | 7 | int main() 8 | { 9 | std::cout << "Enter two numbers: "; 10 | int v1 = 0; 11 | int v2 = 0; 12 | std::cin >> v1 >> v2; 13 | std::cout << "The product of " << v1 << " and " << v2 14 | << " is " << v1 * v2 << std::endl; 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 2 | CMAKE_POLICY(SET CMP0002 OLD) #Allow multiple targets with same name 3 | 4 | PROJECT(CppPrimer) 5 | 6 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -Wextra -Wno-unused-parameter -pedantic -DNDEBUG") 7 | 8 | ADD_SUBDIRECTORY(./Chapter_01) 9 | ADD_SUBDIRECTORY(./Chapter_02) 10 | ADD_SUBDIRECTORY(./Chapter_03) 11 | ADD_SUBDIRECTORY(./Chapter_04) 12 | ADD_SUBDIRECTORY(./Chapter_05) 13 | ADD_SUBDIRECTORY(./Chapter_06) 14 | ADD_SUBDIRECTORY(./Chapter_07) 15 | -------------------------------------------------------------------------------- /Chapter_06/exercise_07.cpp: -------------------------------------------------------------------------------- 1 | // Write a function that returns 0 when it is first called and then 2 | // generates numbers in sequence each time it is called again. 3 | 4 | #include 5 | 6 | using std::cout; 7 | using std::endl; 8 | 9 | int callCounter() 10 | { 11 | static int executionCount = 0; 12 | 13 | return ++executionCount; 14 | } 15 | 16 | int main() 17 | { 18 | for (auto i = 0; i != 10; ++i) 19 | { 20 | cout << callCounter() << endl; 21 | } 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter_01/exercise_22.cpp: -------------------------------------------------------------------------------- 1 | // Write a program that reads several transactions for the same ISBN. 2 | // Write the sum of all the transactions that were read. 3 | 4 | #include 5 | #include "../include/Sales_item.h" 6 | 7 | int main() 8 | { 9 | Sales_item currentTransaction; 10 | Sales_item total; 11 | std::cin >> total; 12 | while (std::cin >> currentTransaction) 13 | { 14 | total += currentTransaction; 15 | } 16 | std::cout << total << std::endl; 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter_03/exercise_15.cpp: -------------------------------------------------------------------------------- 1 | // Repeat the previous program but read strings this time. 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | using std::cout; 9 | using std::cin; 10 | using std::string; 11 | using std::vector; 12 | 13 | 14 | int main() 15 | { 16 | cout << "Enter some words: "; 17 | string userInput; 18 | vector collectedData; 19 | while (cin >> userInput) 20 | { 21 | collectedData.push_back(userInput); 22 | } 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Chapter_04/exercise_04.cpp: -------------------------------------------------------------------------------- 1 | // Parenthesize the following expression to show how it is evaluated. 2 | // Test your answer by compiling the expression (without parentheses) 3 | // and printing its result. 4 | 5 | #include 6 | 7 | using std::cout; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | cout << "Original: " 13 | << 12 / 3 * 4 + 5 * 15 + 24 % 4 / 2 << endl; 14 | cout << "Parenthesized: " 15 | << ((12 / 3) * 4) + (5 * 15) + ((24 % 4) / 2) << endl; 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter_01/exercise_21.cpp: -------------------------------------------------------------------------------- 1 | // Write a program that reads two Sales_item objects that have the same ISBN 2 | // and produces their sum. 3 | 4 | #include 5 | #include "../include/Sales_item.h" 6 | 7 | int main() 8 | { 9 | std::cout << "Enter 2 sale items of the format: ISBN number_sold unit_price" 10 | << std::endl; 11 | Sales_item firstBook; 12 | Sales_item secondBook; 13 | std::cin >> firstBook >> secondBook; 14 | std::cout << firstBook + secondBook << std::endl; 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter_03/exercise_02a.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to read the standard input a line at a time. 2 | // Modify your program to read a word at a time 3 | 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::cin; 9 | using std::endl; 10 | using std::string; 11 | 12 | int main() 13 | { 14 | string userInput; 15 | while (getline(cin, userInput)) 16 | { 17 | if (!userInput.empty()) 18 | { 19 | cout << userInput << endl; 20 | } 21 | } 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter_03/exercise_01a.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the exercises from § 1.4.1 (p. 13) and § 2.6.2 (p. 76) 2 | // with appropriate using declarations. 3 | 4 | // Rewrite of exercise 1.9 5 | 6 | #include 7 | 8 | using std::cout; 9 | using std::endl; 10 | 11 | int main() 12 | { 13 | int sum = 0; 14 | int val = 50; 15 | while (val <= 100) 16 | { 17 | sum += val; 18 | ++val; 19 | } 20 | cout << "The sum of the numbers from 50 to 100 inclusive is: " 21 | << sum << endl; 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter_01/exercise_20.cpp: -------------------------------------------------------------------------------- 1 | // http://www.informit.com/title/032174113 contains a copy of Sales_item.h 2 | // in the Chapter 1 code directory. Copy that file to your working directory. 3 | // Use it to write a program that reads a set of book sales transactions, 4 | // writing each transaction to the standard output. 5 | 6 | #include 7 | #include "../include/Sales_item.h" 8 | 9 | int main() 10 | { 11 | Sales_item book; 12 | while (std::cin >> book) 13 | { 14 | std::cout << book << std::endl; 15 | } 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter_04/exercise_06.cpp: -------------------------------------------------------------------------------- 1 | // Write an expression to determine whether an int value is even or odd 2 | 3 | #include 4 | 5 | using std::cout; 6 | using std::endl; 7 | 8 | int main() 9 | { 10 | int values[10] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 11 | 12 | for (auto element: values) 13 | { 14 | if (element % 2) 15 | { 16 | cout << element << " is odd." << endl; 17 | } 18 | else 19 | { 20 | cout << element << " is even." < 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::endl; 9 | using std::vector; 10 | using std::begin; 11 | using std::end; 12 | 13 | 14 | 15 | int main() 16 | { 17 | const int intArray[] = {1, 2, 3, 4, 5}; 18 | 19 | vector intVector (begin(intArray), end(intArray)); 20 | 21 | for (auto element : intVector) 22 | { 23 | cout << element << endl; 24 | } 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Chapter_01/exercise_13c.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the exercises from 1.4.1 (p. 13) using for loops. 2 | // Exercise 1.11 rewritten using a for loop. 3 | 4 | #include 5 | 6 | int main() 7 | { 8 | std::cout << "Enter a two number range (from low to high): "; 9 | int lowerBound = 0; 10 | int upperBound = 0; 11 | std::cin >> lowerBound >> upperBound; 12 | if (lowerBound < upperBound) 13 | { 14 | for (int i = lowerBound; i <= upperBound; ++i) 15 | { 16 | std::cout << i << std::endl; 17 | } 18 | } 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Chapter_03/exercise_31.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to define an array of ten ints. Give each element 2 | // the same value as its position in the array. 3 | 4 | #include 5 | 6 | using std::cout; 7 | using std::endl; 8 | 9 | int main() 10 | { 11 | constexpr size_t array_size = 10; 12 | int tenInts[array_size]; 13 | 14 | for (size_t i = 0; i != array_size; ++i) 15 | { 16 | tenInts[i] = i; 17 | } 18 | 19 | for (auto element : tenInts) 20 | { 21 | cout << element << " "; 22 | } 23 | cout << endl; 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Chapter_06/fact.cpp: -------------------------------------------------------------------------------- 1 | // Write your own versions of the `fact.cc` and `factMain.cc` files. 2 | // These files should include your `Chapter6.h` from the exercises in 3 | // the previous section. Use these files to understand how your compiler 4 | // supports separate compilation. 5 | 6 | #include "../include/Chapter6.hpp" 7 | 8 | int fact(int n) 9 | { 10 | // if n = 0, nFactorial = 1 11 | // if n > 0, nFactorial = n * (n - 1) * (n - 2)... 12 | int nFactorial = 1; 13 | while (n > 1) 14 | { 15 | nFactorial *= n--; 16 | } 17 | return nFactorial; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter_01/exercise_05.cpp: -------------------------------------------------------------------------------- 1 | // We wrote the output in one large statement. Rewrite the program to use 2 | // a separate statement to print each operand. 3 | 4 | #include 5 | 6 | int main() 7 | { 8 | std::cout << "Enter two numbers: "; 9 | int v1 = 0; 10 | int v2 = 0; 11 | std::cin >> v1; 12 | std::cin >> v2; 13 | std::cout << "The product of "; 14 | std::cout << v1; 15 | std::cout << " and "; 16 | std::cout << v2; 17 | std::cout << " is "; 18 | std::cout << v1 * v2; 19 | std::cout << std::endl; 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Chapter_01/exercise_22b.cpp: -------------------------------------------------------------------------------- 1 | // Write a program that reads several transactions for the same ISBN. 2 | // Write the sum of all the transactions that were read. 3 | 4 | #include 5 | #include "../include/Sales_item.h" 6 | 7 | int main() 8 | { 9 | Sales_item currentTransaction; 10 | Sales_item total; 11 | std::cin >> total; 12 | while (std::cin >> currentTransaction) 13 | { 14 | if (currentTransaction.isbn() == total.isbn()) 15 | { 16 | total += currentTransaction; 17 | } 18 | } 19 | std::cout << total << std::endl; 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Chapter_02/exercise_40.cpp: -------------------------------------------------------------------------------- 1 | // Write your own version of the Sales_data class. 2 | 3 | #include 4 | #include 5 | 6 | struct Sales_data { 7 | std::string bookNo; 8 | unsigned units_sold = 0; 9 | double price = 0.0; 10 | double revenue = 0.0; 11 | }; 12 | 13 | int main() 14 | { 15 | Sales_data sale; 16 | std::cout << "ISBN: " << sale.bookNo << std::endl 17 | << "Units sold: " << sale.units_sold << std::endl 18 | << "Price (each): " << sale.price << std::endl 19 | << "Total revenue: " << sale.revenue << std::endl; 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Chapter_01/exercise_11.cpp: -------------------------------------------------------------------------------- 1 | // Write a program that prompts the user for two integers. Print each 2 | // number in the range specified by those two integers. 3 | 4 | #include 5 | 6 | int main() 7 | { 8 | std::cout << "Enter a two number range (from low to high): "; 9 | int lowerBound = 0; 10 | int upperBound = 0; 11 | std::cin >> lowerBound >> upperBound; 12 | if (lowerBound < upperBound) 13 | { 14 | while (lowerBound <= upperBound) 15 | { 16 | std::cout << lowerBound << std::endl; 17 | ++lowerBound; 18 | } 19 | } 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Chapter_06/exercise_25.cpp: -------------------------------------------------------------------------------- 1 | // Write a `main` function that takes two arguments. 2 | // Concatenate the supplied arguments and print the resulting `string`. 3 | 4 | #include 5 | 6 | using std::cout; 7 | using std::endl; 8 | 9 | int main(int argc, char* argv[]) 10 | { 11 | if (argc == 3) { 12 | cout << argv[1] << " " << argv[2] << endl; 13 | 14 | return 0; 15 | } else if (argc < 3) { 16 | cout << "Too few command line arguments." << endl; 17 | 18 | return -1; 19 | } else { 20 | cout << "Too many command line arguments." << endl; 21 | 22 | return -1; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /include/Person_v2.hpp: -------------------------------------------------------------------------------- 1 | // Provide operations in your Person class to return the name and address. 2 | // Should these functions be const? Explain your choice. 3 | 4 | #ifndef PERSON_V2_HPP 5 | #define PERSON_V2_HPP 6 | 7 | #include 8 | 9 | struct Person 10 | { 11 | std::string name; 12 | std::string address; 13 | std::string get_name() const; 14 | std::string get_address() const; 15 | }; // Person Class 16 | 17 | std::string Person::get_name() const 18 | { 19 | return this->name; 20 | } 21 | 22 | std::string Person::get_address() const 23 | { 24 | return this->address; 25 | } 26 | #endif // PERSON_V2_HPP 27 | -------------------------------------------------------------------------------- /Chapter_06/exercise_21.cpp: -------------------------------------------------------------------------------- 1 | // Write a function that takes an `int` and a pointer to and `int` and returns 2 | // the larger of the `int` value or the value to which the pointer points. 3 | // What type should you use for the pointer? 4 | 5 | #include 6 | 7 | using std::cout; 8 | using std::endl; 9 | 10 | int largestValue(int ival, const int* pval) 11 | { 12 | return ival > *pval ? ival : *pval; 13 | } 14 | 15 | int main() 16 | { 17 | int x = 39; 18 | int y = 44; 19 | 20 | cout << "Compare " << x << " and " << y << endl; 21 | cout << largestValue(x, &y) << " is larger." << endl; 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Chapter_06/exercise_27.cpp: -------------------------------------------------------------------------------- 1 | // Write a function that takes an `initializer_list` and produces 2 | // the sum of the elements in the list. 3 | 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::endl; 9 | using std::initializer_list; 10 | 11 | int get_sum(initializer_list const& values) 12 | { 13 | int sum = 0; 14 | for (auto value : values) { 15 | sum += value; 16 | } 17 | 18 | return sum; 19 | } 20 | 21 | int main() 22 | { 23 | cout << "The sum of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 is: " 24 | << get_sum({ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }) << endl; 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Chapter_06/exercise_33.cpp: -------------------------------------------------------------------------------- 1 | // Write a recursive function to print the contents of a `vector`. 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::endl; 9 | using std::vector; 10 | 11 | void print_vector(vector::const_iterator beg, 12 | vector::const_iterator end) 13 | { 14 | if (beg != end) { 15 | cout << *beg << endl; 16 | print_vector(++beg, end); 17 | } 18 | } 19 | 20 | int main() 21 | { 22 | vector test_vector = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 23 | print_vector(test_vector.cbegin(), test_vector.cend()); 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Chapter_06/factMain.cpp: -------------------------------------------------------------------------------- 1 | // Write your own versions of the `fact.cc` and `factMain.cc` files. 2 | // These files should include your `Chapter6.h` from the exercises in 3 | // the previous section. Use these files to understand how your compiler 4 | // supports separate compilation. 5 | 6 | #include 7 | #include "../include/Chapter6.hpp" 8 | 9 | using std::cin; 10 | using std::cout; 11 | using std::endl; 12 | 13 | int main() 14 | { 15 | cout << "Factorial" << endl 16 | << "Enter an integer: "; 17 | int userInput; 18 | cin >> userInput; 19 | 20 | cout << userInput << "! = " << fact(userInput) << endl; 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Chapter_03/exercise_32b.cpp: -------------------------------------------------------------------------------- 1 | // Copy the array you defined in the previous exercise into another 2 | // array. Rewrite your program using vectors. 3 | 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::endl; 9 | using std::vector; 10 | 11 | int main() 12 | { 13 | int vector_size = 10; 14 | vector tenInts; 15 | 16 | for (auto i = 0; i != vector_size; ++i) 17 | { 18 | tenInts.push_back(i); 19 | } 20 | 21 | vector tenInts_copy = tenInts; 22 | 23 | for (auto element : tenInts_copy) 24 | { 25 | cout << element << " "; 26 | } 27 | cout << endl; 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Chapter_06/exercise_05.cpp: -------------------------------------------------------------------------------- 1 | // Write a function to return the absolute value of it's argument. 2 | 3 | #include 4 | 5 | using std::cin; 6 | using std::cout; 7 | using std::endl; 8 | using std::cerr; 9 | 10 | int getAbsolute(int x) 11 | { 12 | return x < 0 ? -x : x; 13 | } 14 | 15 | int main() 16 | { 17 | cout << "Enter value to convert to absolute vale: "; 18 | int userInput; 19 | if (cin >> userInput) 20 | { 21 | cout << "Absolute value = " << getAbsolute(userInput) << endl; 22 | } 23 | else 24 | { 25 | cerr << endl << "No valid input supplied!" << endl; 26 | 27 | return -1; 28 | } 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Chapter_06/exercise_34.cpp: -------------------------------------------------------------------------------- 1 | // What would happen if the stopping condition in `factorial` were `if (val != 0)` 2 | 3 | #include 4 | 5 | using std::cout; 6 | using std::endl; 7 | 8 | int factorial(int val) 9 | { 10 | static int run_count = 0; 11 | ++run_count; 12 | if (val > 1) { 13 | cout << val << " x "; 14 | return factorial(val - 1) * val; 15 | } 16 | // Here val is always 1 because of the explicit return value below 17 | cout << 1 << endl; 18 | cout << "Function has been run " << run_count << " times.\n"; 19 | return 1; 20 | } 21 | 22 | int main() 23 | { 24 | cout << factorial(5) << endl; 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Chapter_06/exercise_26.cpp: -------------------------------------------------------------------------------- 1 | // Write a `main` function that takes two arguments. 2 | // Concatenate the supplied arguments and print the resulting `string`. 3 | 4 | #include 5 | 6 | using std::cout; 7 | using std::endl; 8 | 9 | int main(int argc, char* argv[]) 10 | { 11 | // This check for null pointer is probably redundant since 12 | // argv will always contain the name of the program as the 13 | // first element. 14 | if (argv) { 15 | // This works because there is a terminating `0` added 16 | // to the end of the argv array 17 | while (*argv) { 18 | cout << *argv++ << endl; 19 | } 20 | } 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Chapter_03/exercise_01c.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the exercises from § 1.4.1 (p. 13) and § 2.6.2 (p. 76) 2 | // with appropriate using declarations. 3 | 4 | // Rewrite of exercise 1.11 5 | 6 | #include 7 | 8 | using std::cout; 9 | using std::cin; 10 | using std::endl; 11 | 12 | int main() 13 | { 14 | cout << "Enter a two number range (from low to high): "; 15 | int lowerBound = 0; 16 | int upperBound = 0; 17 | 18 | cin >> lowerBound >> upperBound; 19 | if (lowerBound < upperBound) 20 | { 21 | while (lowerBound <= upperBound) 22 | { 23 | cout << lowerBound << endl; 24 | ++lowerBound; 25 | } 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Chapter_03/exercise_35.cpp: -------------------------------------------------------------------------------- 1 | // Using pointers, write a program to set the elements in an array to zero. 2 | 3 | #include 4 | #include 5 | 6 | using std::cout; 7 | using std::endl; 8 | using std::begin; 9 | using std::end; 10 | 11 | int main() 12 | { 13 | // Array to reset to zero 14 | int tenInts[10]; 15 | 16 | int* currentElement = begin(tenInts); 17 | int* lastElement = end(tenInts); 18 | 19 | while (currentElement != lastElement) 20 | { 21 | *currentElement = 0; 22 | ++currentElement; 23 | } 24 | 25 | for (auto element : tenInts) 26 | { 27 | cout << element << " "; 28 | } 29 | cout << endl; 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /Chapter_03/exercise_36b.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to compare two arrays for equality. Write a similar 2 | // program to compare two vectors. 3 | 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::endl; 9 | using std::vector; 10 | 11 | int main() 12 | { 13 | // Two vectors for comparison 14 | vector firstVector {1, 2, 3, 4, 5, 6, 7, 8, 9}; 15 | vector secondVector {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 16 | 17 | if (firstVector == secondVector) 18 | { 19 | cout << "Vectors match!" << endl; 20 | 21 | return 0; 22 | } 23 | else 24 | { 25 | cout << "Vectors don't match!" << endl; 26 | 27 | return -1; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Chapter_03/exercise_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::cout; 7 | using std::cin; 8 | using std::endl; 9 | using std::string; 10 | using std::cerr; 11 | 12 | int main() 13 | { 14 | cout << "Enter text to convert: "; 15 | string userInput; 16 | if (cin >> userInput) 17 | { 18 | for (auto& character : userInput) 19 | { 20 | character = 'X'; 21 | } 22 | } 23 | else 24 | { 25 | cerr << endl << "No text entered!" << endl; 26 | 27 | return -1; 28 | } 29 | 30 | cout << "Converted text: " << userInput << endl; 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Chapter_03/exercise_25.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the grade clustering program from § 3.3.3 (p. 104) using 2 | // iterators instead of subscripts. 3 | 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::cin; 9 | using std::endl; 10 | using std::vector; 11 | 12 | int main() 13 | { 14 | vector scores(11, 0); 15 | unsigned grade; 16 | while (cin >> grade) 17 | { 18 | if (grade <= 100) 19 | { 20 | *(scores.begin() + grade / 10) += 1; 21 | } 22 | } 23 | for (auto iter = scores.cbegin(); iter != scores.cend() -1; ++iter) 24 | { 25 | cout << *iter << " "; 26 | } 27 | cout << *(scores.cend() - 1) << endl; 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Chapter_05/exercise_23.cpp: -------------------------------------------------------------------------------- 1 | // Write a program that reads two integers from the standard input and 2 | // prints the result of dividing the first number by the second. 3 | #include 4 | 5 | using std::cin; 6 | using std::cout; 7 | using std::endl; 8 | using std::cerr; 9 | 10 | int main() 11 | { 12 | int intX; 13 | int intY; 14 | cout << "Integer division: x/y" << endl 15 | << "Enter values for 'x' and 'y': "; 16 | if (cin >> intX >> intY) 17 | { 18 | cout << intX << "/" << intY << " = " 19 | << intX / intY << endl; 20 | } 21 | else 22 | { 23 | cerr << endl << "Must supply two integers!" << endl; 24 | return -1; 25 | } 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /Chapter_06/exercise_04.cpp: -------------------------------------------------------------------------------- 1 | // Write and test your own version of `fact`. 2 | 3 | #include 4 | 5 | using std::cin; 6 | using std::cout; 7 | using std::endl; 8 | 9 | int fact(int n) 10 | { 11 | // if n = 0, nFactorial = 1 12 | // if n > 0, nFactorial = n * (n - 1) * (n - 2)... 13 | int nFactorial = 1; 14 | while (n > 1) 15 | { 16 | nFactorial *= n--; 17 | } 18 | return nFactorial; 19 | } 20 | 21 | int getFactorial() 22 | { 23 | cout << "Factorial" << endl 24 | << "Enter an integer: "; 25 | int userInput; 26 | cin >> userInput; 27 | 28 | return fact(userInput); 29 | } 30 | 31 | int main() 32 | { 33 | cout << "Factorial = " << getFactorial() << endl; 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /Chapter_04/exercise_21.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to use a conditional operator to find the elements in a 2 | // `vector` that have odd value and double the value of each such element. 3 | 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::endl; 9 | using std::vector; 10 | 11 | int main() 12 | { 13 | vector ivec {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 14 | 15 | cout << "Original values: "; 16 | 17 | for (auto element : ivec) 18 | { 19 | cout << element << " "; 20 | } 21 | 22 | cout << endl << "New values: "; 23 | 24 | for (auto& element : ivec) 25 | { 26 | cout << ((element % 2) ? element *= 2 : element) << " "; 27 | } 28 | cout << endl; 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /include/Sales_data_v2.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SALES_DATA_V2_HPP 2 | #define SALES_DATA_V2_HPP 3 | 4 | #include 5 | 6 | struct Sales_data 7 | { 8 | std::string bookNo; 9 | unsigned units_sold = 0; 10 | double revenue = 0.0; 11 | std::string isbn() const; 12 | Sales_data& combine(const Sales_data& transaction); 13 | 14 | }; // Sales_data class 15 | 16 | std::string Sales_data::isbn() const 17 | { 18 | return this->bookNo; 19 | } 20 | 21 | Sales_data& Sales_data::combine(const Sales_data& transaction) 22 | { 23 | if (this->isbn() == transaction.isbn()) 24 | { 25 | this->units_sold += transaction.units_sold; 26 | this->revenue += transaction.revenue; 27 | } 28 | return *this; 29 | } 30 | 31 | #endif // SALES_DATA_V2_HPP 32 | -------------------------------------------------------------------------------- /Chapter_03/exercise_32a.cpp: -------------------------------------------------------------------------------- 1 | // Copy the array you defined in the previous exercise into another 2 | // array. Rewrite your program using vectors. 3 | 4 | #include 5 | 6 | using std::cout; 7 | using std::endl; 8 | 9 | int main() 10 | { 11 | constexpr size_t array_size = 10; 12 | int tenInts[array_size]; 13 | 14 | for (size_t i = 0; i != array_size; ++i) 15 | { 16 | tenInts[i] = i; 17 | } 18 | 19 | // Copy tenInts to tenInts_copy 20 | int tenInts_copy[array_size]; 21 | 22 | for (size_t i = 0; i != array_size; ++i) 23 | { 24 | tenInts_copy[i] = tenInts[i]; 25 | } 26 | 27 | for (auto element : tenInts_copy) 28 | { 29 | cout << element << " "; 30 | } 31 | cout << endl; 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Chapter_07/exercise_13.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the program from page 255 to use the istream constructor 2 | 3 | #include 4 | #include "../include/Sales_data_v5.hpp" 5 | 6 | using std::cout; 7 | using std::cin; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | while (cin) 13 | { 14 | static Sales_data total(cin); 15 | if (total.isbn().empty()) 16 | { 17 | cout << "No data?!" << endl; 18 | 19 | return -1; 20 | } 21 | Sales_data trans(cin); 22 | if (total.isbn() == trans.isbn()) 23 | { 24 | total.combine(trans); 25 | } 26 | else 27 | { 28 | print(cout, total) << endl; 29 | total = trans; 30 | } 31 | } 32 | 33 | return 0; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /Chapter_02/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(exercise_04 exercise_04.cpp) 2 | add_executable(exercise_08 exercise_08.cpp) 3 | add_executable(exercise_18 exercise_18.cpp) 4 | add_executable(exercise_34 exercise_34.cpp) 5 | add_executable(exercise_35 exercise_35.cpp) 6 | add_executable(exercise_40 exercise_40.cpp) 7 | add_executable(exercise_41a exercise_41a.cpp) 8 | add_executable(exercise_41b exercise_41b.cpp) 9 | add_executable(exercise_41c exercise_41c.cpp) 10 | add_executable(exercise_41d exercise_41d.cpp) 11 | add_executable(exercise_41f exercise_41f.cpp) 12 | add_executable(exercise_42a exercise_42a.cpp) 13 | add_executable(exercise_42b exercise_42b.cpp) 14 | add_executable(exercise_42c exercise_42c.cpp) 15 | add_executable(exercise_42d exercise_42d.cpp) 16 | add_executable(exercise_42f exercise_42f.cpp) 17 | -------------------------------------------------------------------------------- /Chapter_04/exercise_22a.cpp: -------------------------------------------------------------------------------- 1 | // Extend the program that assigned high pass, pass and fail grades to also 2 | // assign low pass for grades between 60 and 75 inclusive. Write two versions: 3 | // One version that uses only conditional operators; the other should use one 4 | // or more `if` statements. Which version do you think is easier to understand 5 | // and why? 6 | 7 | #include 8 | #include 9 | 10 | using std::cout; 11 | using std::endl; 12 | using std::string; 13 | 14 | int main() 15 | { 16 | // Change this 17 | int grade = 77; 18 | 19 | string finalGrade; 20 | 21 | finalGrade = (grade > 90) ? "High Pass" : 22 | (grade > 75 ? "Pass" : 23 | (grade >= 60) ? "Low Pass" : "Fail"); 24 | 25 | cout << finalGrade << endl; 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /Chapter_06/exercise_51.cpp: -------------------------------------------------------------------------------- 1 | // Write all four versions of f. Each function should print a distinguishing 2 | // message. Check your answers for the previous exercises. If your answers 3 | // were incorrect, study this section until you understand why your answers 4 | // were wrong. 5 | 6 | #include 7 | 8 | using std::cout; 9 | using std::endl; 10 | 11 | void f() 12 | { 13 | cout << "f()" << endl; 14 | } 15 | 16 | void f(int) 17 | { 18 | cout << "f(int)" << endl; 19 | } 20 | 21 | void f(int, int) 22 | { 23 | cout << "f(int, int)" << endl; 24 | } 25 | 26 | void f(double, double = 3.14) 27 | { 28 | cout << "f(double, double = 3.14)" << endl; 29 | } 30 | 31 | int main() 32 | { 33 | // f(2.56, 42); <-- Ambiguous call 34 | f(42); 35 | f(42, 0); 36 | f(2.56, 3.14); 37 | 38 | return 0; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /Chapter_03/exercise_39a.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to compare two strings. Now write a program to compare 2 | // the values of two C-style character strings. 3 | 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::endl; 9 | using std::string; 10 | 11 | int main() 12 | { 13 | string firstString = "Hello"; 14 | string secondString = "Helloo"; 15 | 16 | if (firstString == secondString) 17 | { 18 | cout << "Strings match!" << endl; 19 | } 20 | else if (firstString > secondString) 21 | { 22 | cout << "'" << firstString << "' is greater than '" 23 | << secondString << "'" << endl; 24 | } 25 | else 26 | { 27 | cout << "'" << firstString << "' is less than '" 28 | << secondString << "'" << endl; 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Chapter_01/exercise_21b.cpp: -------------------------------------------------------------------------------- 1 | // Write a program that reads two Sales_item objects that have the same ISBN 2 | // and produces their sum. 3 | 4 | // Updated to check ISBNs match as per section 1.5.2 A first look at member 5 | // functions. 6 | 7 | #include 8 | #include "../include/Sales_item.h" 9 | 10 | int main() 11 | { 12 | std::cout << "Enter 2 sale items of the format: ISBN number_sold unit_price" 13 | << std::endl; 14 | Sales_item firstBook; 15 | Sales_item secondBook; 16 | std::cin >> firstBook >> secondBook; 17 | if (firstBook.isbn() == secondBook.isbn()) 18 | { 19 | std::cout << firstBook + secondBook << std::endl; 20 | 21 | return 0; 22 | } 23 | else 24 | { 25 | std::cerr << "Data must refer to the same ISBN." << std::endl; 26 | 27 | return -1; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Chapter_06/exercise_17b.cpp: -------------------------------------------------------------------------------- 1 | // Write a function to determine whether a `string` contains any capital letters. 2 | // Write a function to change a `string` to all lowercase. Do the parameters you 3 | // used in these functions have the same type? If so, why? If not, why not? 4 | 5 | // Function to change a string to lower case 6 | 7 | #include 8 | #include 9 | 10 | using std::cin; 11 | using std::cout; 12 | using std::endl; 13 | using std::string; 14 | 15 | void toLower(string& s) 16 | { 17 | for (auto& letter : s) 18 | { 19 | letter = tolower(letter); 20 | } 21 | } 22 | 23 | int main() 24 | { 25 | cout << "Enter some text: "; 26 | string userInput; 27 | getline(cin, userInput); 28 | toLower(userInput); 29 | cout << "Converted text: " 30 | << userInput << endl; 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Chapter_06/exercise_10.cpp: -------------------------------------------------------------------------------- 1 | // Using pointers, write a function to swap the values of two ints. Test the 2 | // function by calling it and printing the swapped values. 3 | 4 | #include 5 | 6 | using std::cout; 7 | using std::endl; 8 | 9 | void swapValues(int* x, int* y) 10 | { 11 | int temp = *x; 12 | *x = *y; 13 | *y = temp; 14 | } 15 | 16 | int main() 17 | { 18 | int firstValue = 21; 19 | int secondValue = 43; 20 | 21 | cout << "Starting values:" << endl 22 | << "First value =\t" << firstValue << endl 23 | << "Second value =\t" << secondValue << endl; 24 | 25 | swapValues(&firstValue, &secondValue); 26 | 27 | cout << "Values after calling swapValues:" << endl 28 | << "First value =\t" << firstValue << endl 29 | << "Second value =\t" << secondValue << endl; 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /Chapter_07/exercise_11.cpp: -------------------------------------------------------------------------------- 1 | // Add constructors to your Sales_data class and write a program to use each 2 | // of the constructors. 3 | 4 | #include 5 | #include "../include/Sales_data_v4.hpp" 6 | 7 | using std::cout; 8 | using std::cin; 9 | using std::endl; 10 | 11 | int main() 12 | { 13 | Sales_data first_transaction; 14 | Sales_data second_transaction("0-006-47988-X"); 15 | Sales_data third_transaction("0-006-47988-X", 5, 29.95); 16 | cout << "Enter sale data (isbn, units sold, price each): " << endl; 17 | Sales_data fourth_transaction(cin); 18 | 19 | print(cout, first_transaction); 20 | cout << endl; 21 | print(cout, second_transaction); 22 | cout << endl; 23 | print(cout, third_transaction); 24 | cout << endl; 25 | print(cout, fourth_transaction); 26 | cout << endl; 27 | 28 | return 0; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /Chapter_01/exercise_18.cpp: -------------------------------------------------------------------------------- 1 | // Compile and run the program from this section giving it only 2 | // equal values as input. Run it again gicing it values which no 3 | // number is repeated 4 | 5 | #include 6 | 7 | int main() 8 | { 9 | int currVal = 0, val = 0; 10 | if (std::cin >> currVal) 11 | { 12 | int cnt = 1; 13 | while (std::cin >> val) 14 | { 15 | if (val == currVal) 16 | { 17 | ++cnt; 18 | } 19 | else 20 | { 21 | std::cout << currVal << " occurs " 22 | << cnt << " times " << std::endl; 23 | currVal = val; 24 | cnt = 1; 25 | } 26 | } 27 | std::cout << currVal << " occurs " 28 | << cnt << " times" << std::endl; 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /include/Screen.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SCREEN_HPP 2 | #define SCREEN_HPP 3 | 4 | #include 5 | 6 | class Screen 7 | { 8 | public: 9 | typedef std::string::size_type position; 10 | Screen() = default; 11 | Screen(position height, position width, char value) 12 | : m_height(height) 13 | , m_width(width) 14 | , m_contents(height * width, value) 15 | {} 16 | 17 | char get() const 18 | { 19 | return m_contents[m_cursor]; 20 | } 21 | 22 | char get(position height, position width) const; 23 | 24 | private: 25 | position m_cursor = 0; 26 | position m_height = 0; 27 | position m_width = 0; 28 | std::string m_contents; 29 | }; // Screen class 30 | 31 | inline 32 | char Screen::get(position row, position column) const 33 | { 34 | return m_contents[(row * m_width) + column]; 35 | } 36 | 37 | #endif // SCREEN_HPP 38 | 39 | -------------------------------------------------------------------------------- /Chapter_03/exercise_39b.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to compare two strings. Now write a program to compare 2 | // the values of two C-style character strings. 3 | 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | 13 | const char cStringOne[] = "Hello"; 14 | const char cStringTwo[] = "Helloo"; 15 | 16 | auto cStringComparison = strcmp(cStringOne, cStringTwo); 17 | 18 | if (cStringComparison == 0) 19 | { 20 | cout << "Strings match!" << endl; 21 | } 22 | else if (cStringComparison > 0) 23 | { 24 | cout << "'" << cStringOne << "' is greater than '" 25 | << cStringTwo << "'" << endl; 26 | } 27 | else 28 | { 29 | cout << "'" << cStringOne << "' is less than '" 30 | << cStringTwo << "'" << endl; 31 | } 32 | return 0; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Chapter_05/exercise_06.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite your grading program to use the conditional operator 2 | // (§ 4.7, p. 151) in place of the `if-else` statement. 3 | 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::cin; 9 | using std::endl; 10 | using std::string; 11 | using std::vector; 12 | 13 | int main() 14 | { 15 | vector scores = { "F", "D", "C", "B", "A", "A++" }; 16 | 17 | cout << "Enter you grade (0 - 100): "; 18 | int grade; 19 | cin >> grade; 20 | 21 | string letterGrade; 22 | 23 | letterGrade = (grade < 60) ? scores[0] : 24 | scores[(grade - 50) / 10]; 25 | 26 | letterGrade += (grade < 60 || grade == 100) ? '\0' : 27 | (grade % 10 > 7) ? '+' : 28 | (grade % 10 < 3) ? '-' : '\0'; 29 | 30 | cout << "Score: " << letterGrade << endl; 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Chapter_03/exercise_40.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to define two character arrays initialized from 2 | // string literals. Now define a third character array to hold the 3 | // concatenation of the two arrays. Use strcpy and strcat to copy 4 | // the two 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 firstString[] = "Don't do"; // 8 characters 15 | const char secondString[] = "this!"; // 5 characters 16 | 17 | // firstString + secondString + space + null character 18 | constexpr size_t array_size = 8 + 5 + 1 + 1; 19 | char combinedString[array_size]; 20 | 21 | strcpy(combinedString, firstString); 22 | strcat(combinedString, " "); 23 | strcat(combinedString, secondString); 24 | 25 | cout << combinedString << endl; 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /Chapter_06/exercise_22.cpp: -------------------------------------------------------------------------------- 1 | // Write a function to swap two `int` pointers 2 | 3 | #include 4 | 5 | using std::cout; 6 | using std::endl; 7 | 8 | void swapPointer(int*& ptr1, int*& ptr2) 9 | { 10 | auto temp = ptr1; 11 | ptr1 = ptr2; 12 | ptr2 = temp; 13 | } 14 | 15 | int main() 16 | { 17 | int firstValue = 41; 18 | int secondValue = 55; 19 | 20 | auto firstPointer = &firstValue; 21 | auto secondPointer = &secondValue; 22 | 23 | cout << "Starting values:" << endl 24 | << "First value =\t" << *firstPointer << endl 25 | << "Second value =\t" << *secondPointer << endl; 26 | 27 | swapPointer(firstPointer, secondPointer); 28 | 29 | cout << "Values after calling swapPointer:" << endl 30 | << "First value =\t" << *firstPointer << endl 31 | << "Second value =\t" << *secondPointer << endl; 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Chapter_03/exercise_05a.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to read strings from the standard input, 2 | // concatenating what is read into one large string. Print the 3 | // concatenated string. Next, change the program to separate 4 | // adjacent input strings by a space. 5 | 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::cin; 11 | using std::endl; 12 | using std::string; 13 | 14 | int main() 15 | { 16 | cout << "Enter some text: "; 17 | string userInput; 18 | if (cin >> userInput) 19 | { 20 | string combinedInput = userInput; 21 | while (cin >> userInput) 22 | { 23 | combinedInput += userInput; 24 | } 25 | cout << combinedInput << endl; 26 | } 27 | else 28 | { 29 | std::cerr << endl << "No input to concatenate!" << endl; 30 | 31 | return -1; 32 | 33 | } 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /Chapter_03/exercise_42.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to copy a vector of ints into an array of ints. 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::endl; 9 | using std::vector; 10 | using std::cerr; 11 | using std::begin; 12 | using std::end; 13 | 14 | 15 | int main() { 16 | const vector intVector = {1, 2, 3, 4, 5}; 17 | 18 | int intArray[5]; 19 | 20 | const auto arraySize = end(intArray) - begin(intArray); 21 | 22 | if (intVector.end() - intVector.begin() == arraySize) { 23 | for (auto i = 0; i != arraySize; i++) { 24 | intArray[i] = intVector[i]; 25 | } 26 | } else { 27 | cerr << "Array size does not match vector size!" << endl; 28 | 29 | return -1; 30 | } 31 | 32 | for (auto element : intArray) { 33 | cout << element << endl; 34 | } 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Chapter_03/exercise_05b.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to read strings from the standard input, 2 | // concatenating what is read into one large string. Print the 3 | // concatenated string. Next, change the program to separate 4 | // adjacent input strings by a space. 5 | 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::cin; 11 | using std::endl; 12 | using std::string; 13 | 14 | int main() 15 | { 16 | cout << "Enter some text: "; 17 | string userInput; 18 | if (cin >> userInput) 19 | { 20 | string combinedInput = userInput + " "; 21 | while (cin >> userInput) 22 | { 23 | combinedInput += userInput + " "; 24 | } 25 | cout << combinedInput << endl; 26 | } 27 | else 28 | { 29 | std::cerr << endl << "No input to concatenate!" << endl; 30 | 31 | return -1; 32 | 33 | } 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /Chapter_04/exercise_31.cpp: -------------------------------------------------------------------------------- 1 | // The program in this section used the prefix increment and decrement 2 | // operators. Explain why we used prefix and not postfix. What changes 3 | // would have to be made to use the postfix versions? Rewrite the program 4 | // using postfix operators. 5 | 6 | #include 7 | #include 8 | 9 | using std::vector; 10 | using std::cout; 11 | using std::endl; 12 | 13 | int main() 14 | { 15 | vector ivec (5, 0); 16 | 17 | vector::size_type cnt = ivec.size(); 18 | 19 | // Assign values from cnt... 1 to the elements in ivec 20 | // Prefix or postfix increment/decrement doesn't matter with for loops 21 | for(vector::size_type ix = 0; ix != ivec.size(); ix++, cnt--) 22 | { 23 | ivec[ix] = cnt; 24 | } 25 | 26 | for (auto element : ivec) 27 | { 28 | cout << element << " "; 29 | } 30 | cout << endl; 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Chapter_05/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(exercise_03 exercise_03.cpp) 2 | add_executable(exercise_05 exercise_05.cpp) 3 | add_executable(exercise_06 exercise_06.cpp) 4 | add_executable(exercise_09 exercise_09.cpp) 5 | add_executable(exercise_10a exercise_10a.cpp) 6 | add_executable(exercise_10b exercise_10b.cpp) 7 | add_executable(exercise_11 exercise_11.cpp) 8 | add_executable(exercise_12 exercise_12.cpp) 9 | add_executable(exercise_14 exercise_14.cpp) 10 | add_executable(exercise_16a exercise_16a.cpp) 11 | add_executable(exercise_16b exercise_16b.cpp) 12 | add_executable(exercise_16c exercise_16c.cpp) 13 | add_executable(exercise_16d exercise_16d.cpp) 14 | add_executable(exercise_17 exercise_17.cpp) 15 | add_executable(exercise_20 exercise_20.cpp) 16 | add_executable(exercise_21 exercise_21.cpp) 17 | add_executable(exercise_23 exercise_23.cpp) 18 | add_executable(exercise_24 exercise_24.cpp) 19 | add_executable(exercise_25 exercise_25.cpp) 20 | -------------------------------------------------------------------------------- /Chapter_03/exercise_10.cpp: -------------------------------------------------------------------------------- 1 | // Write a program that reads a string of characters including punctuation 2 | // and writes what was read but with the punctuation removed. 3 | 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::cin; 9 | using std::endl; 10 | using std::string; 11 | using std::cerr; 12 | 13 | int main() 14 | { 15 | cout << "Enter text with punctuation: "; 16 | string userInput; 17 | if (cin >> userInput) 18 | { 19 | string cleanOutput; 20 | for (auto character : userInput) 21 | { 22 | if (!ispunct(character)) 23 | { 24 | cleanOutput += character; 25 | } 26 | } 27 | cout << "Punctuation has been stripped: " << cleanOutput << endl; 28 | 29 | return 0; 30 | } 31 | else 32 | { 33 | cerr << endl << "No text entered!" << endl; 34 | 35 | return -1; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Chapter_05/exercise_16b.cpp: -------------------------------------------------------------------------------- 1 | // The `while` loop is particularly good at executing while some condition 2 | // holds; for example, when we need to read values until end-of-file. The 3 | // `for` loop is generally thought of as a step loop: An index steps through 4 | // a range of values in a collection. Write an idiomatic use of each loop 5 | // and then rewrite each using the other loop construct. If you could use 6 | // only one loop, which would you choose? Why? 7 | 8 | // `for` use case. 9 | 10 | #include 11 | 12 | using std::cin; 13 | using std::cout; 14 | using std::endl; 15 | 16 | int main() 17 | { 18 | cout << "Enter a number: "; 19 | int userInput; 20 | cin >> userInput; 21 | int sum = 0; 22 | for (auto i = 1; i <= userInput; ++i) 23 | { 24 | sum += i; 25 | } 26 | 27 | cout << "Sum of 1 to " << userInput << " inclusive is: " 28 | << sum << endl; 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Chapter_06/exercise_12.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the program from [exercise 6.10](exercise_10.cpp) in § 6.2.1 (p. 210) 2 | // to use references instead of pointers to swap the value of two ints. Which 3 | // version do you think would be eaisier to use and why? 4 | 5 | #include 6 | 7 | using std::cout; 8 | using std::endl; 9 | 10 | void swapValues(int& x, int& y) 11 | { 12 | int temp = x; 13 | x = y; 14 | y = temp; 15 | } 16 | 17 | int main() 18 | { 19 | int firstValue = 21; 20 | int secondValue = 43; 21 | 22 | cout << "Starting values:" << endl 23 | << "First value =\t" << firstValue << endl 24 | << "Second value =\t" << secondValue << endl; 25 | 26 | swapValues(firstValue, secondValue); 27 | 28 | cout << "Values after calling swapValues:" << endl 29 | << "First value =\t" << firstValue << endl 30 | << "Second value =\t" << secondValue << endl; 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Chapter_01/exercise_23.cpp: -------------------------------------------------------------------------------- 1 | // Write a program that reads several transactions and counts how many 2 | // transactions occur for each ISBN. 3 | 4 | #include 5 | #include "../include/Sales_item.h" 6 | 7 | int main() 8 | { 9 | Sales_item currentTransaction; 10 | Sales_item total; 11 | if (std::cin >> currentTransaction) 12 | { 13 | int totalTransactions = 1; 14 | while (std::cin >> total) 15 | { 16 | if (currentTransaction.isbn() == total.isbn()) 17 | { 18 | ++totalTransactions; 19 | } 20 | else 21 | { 22 | std::cout << totalTransactions << " Transaction(s) for ISBN '" 23 | << currentTransaction.isbn() << "'" << std::endl; 24 | totalTransactions = 1; 25 | currentTransaction = total; 26 | } 27 | } 28 | } 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Chapter_03/exercise_08b.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the program in the first exercise, first using a while and 2 | // again using a traditional for loop. Which of the three aproaches do 3 | // you prefer and why? 4 | 5 | // Rewrite of Exercise 3.6 using a traditional for loop 6 | 7 | #include 8 | #include 9 | 10 | using std::cout; 11 | using std::cin; 12 | using std::endl; 13 | using std::string; 14 | using std::cerr; 15 | 16 | int main() 17 | { 18 | cout << "Enter text to convert: "; 19 | string userInput; 20 | if (cin >> userInput) 21 | { 22 | for (decltype(userInput.size()) index = 0; 23 | index < userInput.size(); ++index) 24 | { 25 | userInput[index] = 'X'; 26 | } 27 | } 28 | else 29 | { 30 | cerr << endl << "No text entered!" << endl; 31 | 32 | return -1; 33 | } 34 | 35 | cout << "Converted text: " << userInput << endl; 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /Chapter_03/exercise_08a.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the program in the first exercise, first using a while and 2 | // again using a traditional for loop. Which of the three aproaches do 3 | // you prefer and why? 4 | 5 | // Rewrite of Exercise 3.6 using a while loop 6 | 7 | #include 8 | #include 9 | 10 | using std::cout; 11 | using std::cin; 12 | using std::endl; 13 | using std::string; 14 | using std::cerr; 15 | 16 | int main() 17 | { 18 | cout << "Enter text to convert: "; 19 | string userInput; 20 | if (cin >> userInput) 21 | { 22 | decltype(userInput.size()) index = 0; 23 | while (index < userInput.size()) 24 | { 25 | userInput[index] = 'X'; 26 | ++index; 27 | } 28 | } 29 | else 30 | { 31 | cerr << endl << "No text entered!" << endl; 32 | 33 | return -1; 34 | } 35 | 36 | cout << "Converted text: " << userInput << endl; 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /Chapter_03/exercise_23.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to create a vector with ten int elements. Using an 2 | // iterator, assign each element a value that is twice its current value. 3 | // Test your program by printing the vector. 4 | 5 | #include 6 | #include 7 | 8 | using std::cout; 9 | using std::cin; 10 | using std::endl; 11 | using std::vector; 12 | 13 | int main() 14 | { 15 | cout << "Enter ten integers: "; 16 | vector userInput(10); 17 | for (auto iter = userInput.begin(); iter != userInput.end(); ++iter) 18 | { 19 | cin >> *iter; 20 | } 21 | 22 | for (auto iter = userInput.begin(); iter != userInput.end(); ++iter) 23 | { 24 | *iter *= 2; 25 | } 26 | 27 | cout << "Result: "; 28 | for (auto iter = userInput.cbegin(); iter != userInput.cend() - 1; ++iter) 29 | { 30 | cout << *iter << ", "; 31 | } 32 | cout << *(userInput.cend() - 1) << endl; 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Chapter_05/exercise_03.cpp: -------------------------------------------------------------------------------- 1 | // Use the comma operator (§ 4.10, p. 157) to rewrite the while 2 | // loop from § 1.4.1 (p. 11) so that it no longer requires a block. 3 | // Explain whether this rewrite improves or diminishes the readability 4 | // of this code. 5 | 6 | #include 7 | 8 | using std::cout; 9 | using std::endl; 10 | 11 | int main() 12 | { 13 | int sum = 0; 14 | int val = 1; 15 | 16 | // Original code 17 | // keep executing the while as long as val is less than or equal to 10 18 | // while (val <= 10) 19 | // { 20 | // sum += val; // assigns sum + val to sum 21 | // ++val; // add 1 to val 22 | // } 23 | // cout << "Sum of 1 to 10 inclusive is " 24 | // << sum << endl; 25 | 26 | // Rewrite using comma operator 27 | while (val <= 10) 28 | sum += val, ++val; 29 | 30 | cout << "Sum of 1 to 10 inclusive is " 31 | << sum << endl; 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Chapter_01/exercise_19.cpp: -------------------------------------------------------------------------------- 1 | // Revise the program you wrote for the exercises in § 1.4.1 (p.13) that 2 | // printed a range of numbers so that it handles input in which the first 3 | // number is smaller than the second. 4 | 5 | // Rewrite of exercise 1.11 to handle incorrect range input 6 | 7 | #include 8 | 9 | int main() 10 | { 11 | std::cout << "Enter a two number range: "; 12 | int lowerBound = 0; 13 | int upperBound = 0; 14 | std::cin >> lowerBound >> upperBound; 15 | if (lowerBound > upperBound) 16 | { 17 | auto temp = lowerBound; // store the high number in a temp variable 18 | lowerBound = upperBound; // assign the low number to the correct variable 19 | upperBound = temp; // assign the high number to the correct variable 20 | } 21 | 22 | while (lowerBound <= upperBound) 23 | { 24 | std::cout << lowerBound << std::endl; 25 | ++lowerBound; 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Chapter_05/exercise_24.cpp: -------------------------------------------------------------------------------- 1 | // Revise your program to `throw` an exception if the second number is zero. 2 | // Test your program with a zero input to see what happens on your system 3 | // if you don't catch an exception. 4 | 5 | #include 6 | #include 7 | 8 | using std::cin; 9 | using std::cout; 10 | using std::endl; 11 | using std::runtime_error; 12 | using std::cerr; 13 | 14 | int main() 15 | { 16 | int intX; 17 | int intY; 18 | cout << "Integer division: x/y" << endl 19 | << "Enter values for 'x' and 'y': "; 20 | if (cin >> intX >> intY) 21 | { 22 | if (intY == 0) 23 | { 24 | throw runtime_error("Divide-by-zero exception."); 25 | } 26 | cout << intX << "/" << intY << " = " 27 | << intX / intY << endl; 28 | } 29 | else 30 | { 31 | cerr << endl << "Must supply two integers!" << endl; 32 | return -1; 33 | } 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /Chapter_03/exercise_24a.cpp: -------------------------------------------------------------------------------- 1 | // Redo the last exercise from § 3.3.3 (p. 105) using iterators. 2 | 3 | #include 4 | #include 5 | 6 | using std::cout; 7 | using std::cin; 8 | using std::endl; 9 | using std::vector; 10 | using std::cerr; 11 | 12 | int main() 13 | { 14 | cout << "Enter some numbers: "; 15 | int userInput; 16 | if (cin >> userInput) 17 | { 18 | vector userData {userInput}; 19 | while (cin >> userInput) 20 | { 21 | userData.push_back(userInput); 22 | } 23 | 24 | if (userData.size() > 1) 25 | { 26 | for (auto iter = userData.cbegin(); 27 | iter < userData.cend() - 1; ++iter) 28 | { 29 | cout << *iter + *(iter + 1) << " "; 30 | } 31 | cout << endl; 32 | 33 | return 0; 34 | } 35 | } 36 | cerr << endl << "Need at least two numbers." << endl; 37 | 38 | return -1; 39 | } 40 | -------------------------------------------------------------------------------- /Chapter_04/exercise_22b.cpp: -------------------------------------------------------------------------------- 1 | // Extend the program that assigned high pass, pass and fail grades to also 2 | // assign low pass for grades between 60 and 75 inclusive. Write two versions: 3 | // One version that uses only conditional operators; the other should use one 4 | // or more `if` statements. Which version do you think is easier to understand 5 | // and why? 6 | 7 | #include 8 | #include 9 | 10 | using std::cout; 11 | using std::endl; 12 | using std::string; 13 | 14 | int main() 15 | { 16 | // Change this 17 | int grade = 77; 18 | 19 | string finalGrade; 20 | 21 | if (grade > 90) 22 | { 23 | finalGrade = "High Pass"; 24 | } 25 | else if (grade > 75) 26 | { 27 | finalGrade = "Pass"; 28 | } 29 | else if (grade >= 60) 30 | { 31 | finalGrade = "Low Pass"; 32 | } 33 | else 34 | { 35 | finalGrade = "Fail"; 36 | } 37 | 38 | cout << finalGrade << endl; 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /Chapter_05/exercise_16d.cpp: -------------------------------------------------------------------------------- 1 | // The `while` loop is particularly good at executing while some condition 2 | // holds; for example, when we need to read values until end-of-file. The 3 | // `for` loop is generally thought of as a step loop: An index steps through 4 | // a range of values in a collection. Write an idiomatic use of each loop 5 | // and then rewrite each using the other loop construct. If you could use 6 | // only one loop, which would you choose? Why? 7 | 8 | // `for` use case rewritten using a `while` loop 9 | 10 | #include 11 | 12 | using std::cin; 13 | using std::cout; 14 | using std::endl; 15 | 16 | int main() 17 | { 18 | cout << "Enter a number: "; 19 | int userInput; 20 | cin >> userInput; 21 | int sum = 0; 22 | int i = 1; 23 | while (i <= userInput) 24 | { 25 | sum += i; 26 | ++i; 27 | } 28 | 29 | cout << "Sum of 1 to " << userInput << " inclusive is: " 30 | << sum << endl; 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Chapter_05/exercise_05.cpp: -------------------------------------------------------------------------------- 1 | // Using an `if-else` statement, write your own version of the program 2 | // to generate the letter grade from a numeric grade. 3 | 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::cin; 9 | using std::endl; 10 | using std::string; 11 | using std::vector; 12 | 13 | int main() 14 | { 15 | vector scores = { "F", "D", "C", "B", "A", "A++" }; 16 | 17 | cout << "Enter you grade (0 - 100): "; 18 | int grade; 19 | cin >> grade; 20 | 21 | string letterGrade; 22 | if (grade < 60) 23 | { 24 | letterGrade = scores[0]; 25 | } 26 | else 27 | { 28 | letterGrade = scores[(grade - 50) / 10]; 29 | 30 | if (grade % 10 > 7) 31 | { 32 | letterGrade += '+'; 33 | } 34 | else if (grade % 10 < 3) 35 | { 36 | letterGrade += '-'; 37 | } 38 | } 39 | 40 | cout << "Score: " << letterGrade << endl; 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Chapter_06/exercise_17a.cpp: -------------------------------------------------------------------------------- 1 | // Write a function to determine whether a `string` contains any capital letters. 2 | // Write a function to change a `string` to all lowercase. Do the parameters you 3 | // used in these functions have the same type? If so, why? If not, why not? 4 | 5 | // Function to check if a string has upper case characters 6 | 7 | #include 8 | #include 9 | 10 | using std::cin; 11 | using std::cout; 12 | using std::endl; 13 | using std::string; 14 | 15 | bool hasUpperCase(const string& s) 16 | { 17 | for (auto letter : s) 18 | { 19 | if (isupper(letter)) 20 | { 21 | return true; 22 | } 23 | } 24 | return false; 25 | } 26 | 27 | int main() 28 | { 29 | cout << "Enter some text: "; 30 | string userInput; 31 | getline(cin, userInput); 32 | cout << "The text you entered has " 33 | << (hasUpperCase(userInput) ? "" : "no ") 34 | << "upper case characters." << endl; 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Chapter_03/exercise_07.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::cout; 7 | using std::cin; 8 | using std::endl; 9 | using std::string; 10 | using std::cerr; 11 | 12 | int main() 13 | { 14 | cout << "Enter text to convert: "; 15 | string userInput; 16 | if (cin >> userInput) 17 | { 18 | for (char character : userInput) 19 | { 20 | // character is now a local variable making any 21 | // change here will do nothing to userInput. The 22 | // compiler will warn of an unused variable since we've 23 | // set the value 'X' but never used character in the 24 | // program. 25 | character = 'X'; 26 | } 27 | } 28 | else 29 | { 30 | cerr << endl << "No text entered!" << endl; 31 | 32 | return -1; 33 | } 34 | 35 | cout << "Not-so-converted text: " << userInput << endl; 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /Chapter_01/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(exercise_01 exercise_01.cpp) 2 | add_executable(exercise_02 exercise_02.cpp) 3 | add_executable(exercise_03 exercise_03.cpp) 4 | add_executable(exercise_04 exercise_04.cpp) 5 | add_executable(exercise_05 exercise_05.cpp) 6 | add_executable(exercise_09 exercise_09.cpp) 7 | add_executable(exercise_10 exercise_10.cpp) 8 | add_executable(exercise_11 exercise_11.cpp) 9 | add_executable(exercise_13a exercise_13a.cpp) 10 | add_executable(exercise_13b exercise_13b.cpp) 11 | add_executable(exercise_13c exercise_13c.cpp) 12 | add_executable(exercise_16 exercise_16.cpp) 13 | add_executable(exercise_18 exercise_18.cpp) 14 | add_executable(exercise_19 exercise_19.cpp) 15 | add_executable(exercise_20 exercise_20.cpp) 16 | add_executable(exercise_21 exercise_21.cpp) 17 | add_executable(exercise_21b exercise_21b.cpp) 18 | add_executable(exercise_22 exercise_22.cpp) 19 | add_executable(exercise_22b exercise_22b.cpp) 20 | add_executable(exercise_23 exercise_23.cpp) 21 | add_executable(exercise_25 exercise_25.cpp) 22 | -------------------------------------------------------------------------------- /Chapter_06/exercise_55.cpp: -------------------------------------------------------------------------------- 1 | // Write four functions that add, subtract, multiply and divide two int values. 2 | // Store pointers to these functions in your vector from the previous exercise. 3 | 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::endl; 9 | using std::vector; 10 | 11 | int add(int x, int y) 12 | { 13 | return x + y; 14 | } 15 | 16 | int subtract(int x, int y) 17 | { 18 | return x - y; 19 | } 20 | 21 | int multiply(int x, int y) 22 | { 23 | return x * y; 24 | } 25 | 26 | // Must use int as return type so it can be stored in the vector 27 | // return type of double would probably be more useful though 28 | int divide(int x, int y) 29 | { 30 | return y != 0 ? x / y : 0; 31 | } 32 | 33 | int main() 34 | { 35 | typedef decltype(add)* FP; 36 | vector arithmetic_vec = {add, subtract, multiply, divide}; 37 | 38 | for (auto arithmetic_operator : arithmetic_vec) 39 | { 40 | cout << arithmetic_operator(10, 10) << endl; 41 | } 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Chapter_02/exercise_04.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to check whether your predictions were correct 2 | // If not study this section until you understand what the problem is. 3 | 4 | #include 5 | 6 | int main() 7 | { 8 | unsigned u = 10; 9 | unsigned u2 = 42; 10 | std::cout << "unsigned int " << u2 << " - " << "unsigned int " 11 | << u << " = " << u2 - u << std::endl; 12 | std::cout << "unsigned int " << u << " - " << "unsigned int " 13 | << u2 << " = " << u - u2 << std::endl; 14 | 15 | int i = 10; 16 | int i2 = 42; 17 | std::cout << "int " << i2 << " - " << "int " < test_vector = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 30 | print_vector(test_vector.cbegin(), test_vector.cend()); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Chapter_07/exercise_07.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the transaction-processing program from § 7.1.2 (p. 260) to use 2 | // these new functions. 3 | 4 | #include 5 | #include 6 | #include "../include/Sales_data_v3.hpp" 7 | 8 | using std::cin; 9 | using std::cout; 10 | using std::endl; 11 | using std::string; 12 | 13 | int main() 14 | { 15 | Sales_data total; 16 | if (read(cin, total)) 17 | { 18 | Sales_data transaction; 19 | while (read(cin, transaction)) 20 | { 21 | if (total.isbn() == transaction.isbn()) 22 | { 23 | total.combine(transaction); 24 | } 25 | else 26 | { 27 | print(cout, total); 28 | cout << endl; 29 | total = transaction; 30 | } 31 | } 32 | print(cout, total); 33 | cout << endl; 34 | } 35 | else 36 | { 37 | std::cerr << "No data?!" << endl; 38 | 39 | return -1; 40 | } 41 | 42 | return 0; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /Chapter_05/exercise_16a.cpp: -------------------------------------------------------------------------------- 1 | // The `while` loop is particularly good at executing while some condition 2 | // holds; for example, when we need to read values until end-of-file. The 3 | // `for` loop is generally thought of as a step loop: An index steps through 4 | // a range of values in a collection. Write an idiomatic use of each loop 5 | // and then rewrite each using the other loop construct. If you could use 6 | // only one loop, which would you choose? Why? 7 | 8 | // `while` use case. 9 | 10 | #include 11 | #include 12 | 13 | using std::cin; 14 | using std::cout; 15 | using std::endl; 16 | using std::vector; 17 | 18 | int main() 19 | { 20 | cout << "Enter some numbers: "; 21 | vector buffer; 22 | int userInput; 23 | while (cin >> userInput) 24 | { 25 | buffer.push_back(userInput); 26 | } 27 | 28 | // Print buffer 29 | cout << "You entered: "; 30 | for (auto number : buffer) 31 | { 32 | cout << number << " "; 33 | } 34 | cout << endl; 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Chapter_05/exercise_17.cpp: -------------------------------------------------------------------------------- 1 | // Given two `vectors` of ints, write a program to determine whether 2 | // one `vector` is a prefix of the other. For vectors of unequal length, 3 | // compare the number of elements of the smaller `vector`. For example, 4 | // given the vectors containing `0, 1, 1` and `2` and `0, 1, 1, 2, 3, 5, 8`, 5 | // respectively your program should return true. 6 | 7 | #include 8 | #include 9 | 10 | using std::cout; 11 | using std::endl; 12 | using std::vector; 13 | 14 | int main() 15 | { 16 | // Change these 17 | vector ivec { 0, 1, 1, 2 }; 18 | vector ivec2 { 0, 1, 1, 2, 3, 5, 8 }; 19 | 20 | vector* shortestVector = ivec.size() > ivec2.size() ? &ivec2 : &ivec; 21 | decltype(shortestVector->size()) i = 0; 22 | 23 | for ( /* init not required */; 24 | ivec[i] == ivec2[i] && i != shortestVector->size(); 25 | ++i) 26 | { 27 | // body not required 28 | } 29 | 30 | cout << (i < shortestVector->size() ? "False" : "True") << endl; 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Chapter_07/exercise_02.cpp: -------------------------------------------------------------------------------- 1 | // Add the combine and isbn members to the Sales_data class you wrote for the 2 | // exercises in § 2.6.2 (p. 76). 3 | 4 | #include 5 | #include 6 | #include "../include/Sales_data_v2.hpp" 7 | 8 | void print_data(const Sales_data& data) 9 | { 10 | std::cout << "\tISBN: " << data.bookNo << std::endl 11 | << "\tUnits sold: " << data.units_sold << std::endl 12 | << "\tTotal revenue: " << data.revenue << std::endl; 13 | } 14 | 15 | int main() 16 | { 17 | Sales_data total; 18 | Sales_data sale; 19 | 20 | total.bookNo = "0-006-47988"; 21 | total.units_sold = 10; 22 | total.revenue = 50.0; 23 | 24 | sale.bookNo = "0-006-47988"; 25 | sale.units_sold = 5; 26 | sale.revenue = 50.0; 27 | 28 | std::cout << "First transaction:" << std::endl; 29 | print_data(total); 30 | std::cout << "Second transaction:" << std::endl; 31 | print_data(sale); 32 | std::cout << "Transactions combined:" << std::endl; 33 | print_data(total.combine(sale)); 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /Chapter_03/exercise_45a.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the programs again, this time using auto. 2 | 3 | #include 4 | 5 | using std::cout; 6 | using std::endl; 7 | 8 | int main() 9 | { 10 | // Dimensions of array 11 | constexpr size_t rowCount = 3; 12 | constexpr size_t colCount = 4; 13 | 14 | int ia[rowCount][colCount]; 15 | 16 | // Fill ia (using auto) 17 | size_t count = 0; 18 | 19 | for (auto& row : ia) 20 | { 21 | for (auto& col : row) 22 | { 23 | col = count; 24 | ++count; 25 | } 26 | } 27 | // Initialisation code above is the same for all versions of this 28 | // exercise (pointer version includes the iterator header and using 29 | // declarations for begin and end). 30 | 31 | // Print output using range for loop (using auto) 32 | cout << "Using 'range for' & auto:" << endl; 33 | for (const auto& row : ia) 34 | { 35 | for (auto col : row) 36 | { 37 | cout << col << " "; 38 | } 39 | cout << endl; 40 | } 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Chapter_03/exercise_36a.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to compare two arrays for equality. Write a similar 2 | // program to compare two vectors. 3 | 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::endl; 9 | using std::begin; 10 | using std::end; 11 | 12 | int main() 13 | { 14 | // Two arrays for comparison 15 | int firstArray[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 16 | int secondArray[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 17 | 18 | int* ia2element = secondArray; 19 | 20 | if (end(firstArray) - begin(firstArray) == 21 | end(secondArray) - begin(secondArray)) 22 | { 23 | for (auto element : firstArray) 24 | { 25 | if (element != *ia2element) 26 | { 27 | cout << "Arrays do not match!" << endl; 28 | 29 | return -1; 30 | } 31 | ++ia2element; 32 | } 33 | cout << "Arrays match!" << endl; 34 | 35 | return 0; 36 | } 37 | else 38 | { 39 | cout << "Arrays do not match!" << endl; 40 | 41 | return -1; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Chapter_03/exercise_45b.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the programs again, this time using auto. 2 | 3 | #include 4 | 5 | using std::cout; 6 | using std::endl; 7 | 8 | int main() 9 | { 10 | // Dimensions of array 11 | constexpr size_t rowCount = 3; 12 | constexpr size_t colCount = 4; 13 | 14 | int ia[rowCount][colCount]; 15 | 16 | // Fill ia (using auto) 17 | size_t count = 0; 18 | 19 | for (auto& row : ia) 20 | { 21 | for (auto& col : row) 22 | { 23 | col = count; 24 | ++count; 25 | } 26 | } 27 | // Initialisation code above is the same for all versions of this 28 | // exercise (pointer version includes the iterator header and using 29 | // declarations for begin and end). 30 | 31 | // Print output using subscript (using auto) 32 | cout << "Using 'subscript' & auto:" << endl; 33 | for (auto i = 0; i != rowCount; ++i) 34 | { 35 | for (auto j = 0; j != colCount; ++j) 36 | { 37 | cout << ia[i][j] << " "; 38 | } 39 | cout << endl; 40 | } 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Chapter_05/exercise_16c.cpp: -------------------------------------------------------------------------------- 1 | // The `while` loop is particularly good at executing while some condition 2 | // holds; for example, when we need to read values until end-of-file. The 3 | // `for` loop is generally thought of as a step loop: An index steps through 4 | // a range of values in a collection. Write an idiomatic use of each loop 5 | // and then rewrite each using the other loop construct. If you could use 6 | // only one loop, which would you choose? Why? 7 | 8 | // `while` use case rewritten using `for` loop. 9 | 10 | #include 11 | #include 12 | 13 | using std::cin; 14 | using std::cout; 15 | using std::endl; 16 | using std::vector; 17 | 18 | int main() 19 | { 20 | cout << "Enter some numbers: "; 21 | vector buffer; 22 | int userInput; 23 | for (/* not required */; cin >> userInput; buffer.push_back(userInput)) 24 | { 25 | // not required 26 | } 27 | 28 | // Print buffer 29 | cout << "You entered: "; 30 | for (auto number : buffer) 31 | { 32 | cout << number << " "; 33 | } 34 | cout << endl; 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /include/Person_v3.hpp: -------------------------------------------------------------------------------- 1 | // Provide operations in your Person class to return the name and address. 2 | // Should these functions be const? Explain your choice. 3 | 4 | #ifndef PERSON_V3_HPP 5 | #define PERSON_V3_HPP 6 | 7 | #include 8 | #include 9 | 10 | struct Person 11 | { 12 | std::string name; 13 | std::string address; 14 | std::string get_name() const; 15 | std::string get_address() const; 16 | std::istream& read(std::istream& input, Person& person); 17 | std::ostream& print(std::ostream& output, const Person& person); 18 | }; // Person Class 19 | 20 | std::string Person::get_name() const 21 | { 22 | return this->name; 23 | } 24 | 25 | std::string Person::get_address() const 26 | { 27 | return this->address; 28 | } 29 | 30 | std::istream& read(std::istream& input, Person& person) 31 | { 32 | input >> person.name >> person.address; 33 | return input; 34 | } 35 | 36 | std::ostream& print(std::ostream& output, const Person& person) 37 | { 38 | output << person.name << " " << person.address; 39 | return output; 40 | } 41 | 42 | #endif // PERSON_V3_HPP 43 | -------------------------------------------------------------------------------- /Chapter_06/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(exercise_03 exercise_03.cpp) 2 | add_executable(exercise_04 exercise_04.cpp) 3 | add_executable(exercise_05 exercise_05.cpp) 4 | add_executable(exercise_07 exercise_07.cpp) 5 | add_executable(factorial fact.cpp factMain.cpp) 6 | add_executable(exercise_10 exercise_10.cpp) 7 | add_executable(exercise_11 exercise_11.cpp) 8 | add_executable(exercise_12 exercise_12.cpp) 9 | add_executable(exercise_17a exercise_17a.cpp) 10 | add_executable(exercise_17b exercise_17b.cpp) 11 | add_executable(exercise_21 exercise_21.cpp) 12 | add_executable(exercise_22 exercise_22.cpp) 13 | add_executable(exercise_23 exercise_23.cpp) 14 | add_executable(exercise_25 exercise_25.cpp) 15 | add_executable(exercise_26 exercise_26.cpp) 16 | add_executable(exercise_27 exercise_27.cpp) 17 | add_executable(exercise_33 exercise_33.cpp) 18 | add_executable(exercise_34 exercise_34.cpp) 19 | add_executable(exercise_37 exercise_37.cpp) 20 | add_executable(exercise_42 exercise_42.cpp) 21 | add_executable(exercise_47 exercise_47.cpp) 22 | add_executable(exercise_51 exercise_51.cpp) 23 | add_executable(exercise_55 exercise_55.cpp) 24 | 25 | -------------------------------------------------------------------------------- /Chapter_03/exercise_45c.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the programs again, this time using auto. 2 | 3 | #include 4 | #include 5 | 6 | using std::cout; 7 | using std::endl; 8 | using std::begin; 9 | using std::end; 10 | 11 | int main() 12 | { 13 | // Dimensions of array 14 | constexpr size_t rowCount = 3; 15 | constexpr size_t colCount = 4; 16 | 17 | int ia[rowCount][colCount]; 18 | 19 | // Fill ia (using auto) 20 | size_t count = 0; 21 | 22 | for (auto& row : ia) 23 | { 24 | for (auto& col : row) 25 | { 26 | col = count; 27 | ++count; 28 | } 29 | } 30 | // Initialisation code above is the same for all versions of this 31 | // exercise (pointer version includes the iterator header and using 32 | // declarations for begin and end). 33 | 34 | // Print output using pointers (using auto) 35 | cout << "Using 'pointers' & auto:" << endl; 36 | for (auto* p = begin(ia); p != end(ia); ++p) 37 | { 38 | for (auto* q = begin(*p); q != end(*p); ++q) 39 | { 40 | cout << *q << " "; 41 | } 42 | cout << endl; 43 | } 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /Chapter_06/exercise_42.cpp: -------------------------------------------------------------------------------- 1 | // Give the second parameter of make_plural a default argument of 's'. Test 2 | // your program by printing singular and plural versions of the words 3 | // `success` and `failure`. 4 | 5 | #include 6 | #include 7 | 8 | using std::cout; 9 | using std::endl; 10 | using std::string; 11 | 12 | // Original function from textbook 13 | string make_plural(size_t ctr, const string& word, const string& ending) 14 | { 15 | return (ctr > 1) ? word + ending : word; 16 | } 17 | 18 | // New function with third parameter defaulting to 's' since changing the 19 | // second makes no sense. 20 | string new_make_plural(size_t ctr, const string& word, const string& ending = "s") 21 | { 22 | return (ctr > 1) ? word + ending : word; 23 | } 24 | 25 | int main() 26 | { 27 | // Ending needs to be 'es' so we need to supply an ending 28 | cout << new_make_plural(1, "success", "es") << endl 29 | << new_make_plural(2, "success", "es") << endl; 30 | // Default value is 's' so we don't have to supply an ending here 31 | cout << new_make_plural(1, "failure") << endl 32 | << new_make_plural(2, "failure") << endl; 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Chapter_02/exercise_18.cpp: -------------------------------------------------------------------------------- 1 | // Write code to change the value of a pointer. 2 | // Write code to change the value to which the pointer points. 3 | 4 | #include 5 | 6 | int main() 7 | { 8 | int v1 = 10; 9 | int v2 = 20; 10 | int *p1 = &v1; 11 | std::cout << "Initial variables:" << std::endl 12 | << "v1 = " << v1 << std::endl 13 | << "v2 = " << v2 << std::endl 14 | << "Initial pointer to v1:" << std::endl 15 | << "p1 value: " << *p1 << std::endl 16 | << "p1 address: " << p1 << std::endl; 17 | 18 | std::cout << "------------------------------" << std::endl; 19 | 20 | // change value of pointer 21 | p1 = &v2; 22 | std::cout << "Change p1 to point to v2:" << std::endl; 23 | std::cout << "p1 value: " << *p1 << std::endl; 24 | std::cout << "p1 address: " << p1 << std::endl; 25 | 26 | std::cout << "------------------------------" << std::endl; 27 | 28 | // change value to which the pointer points 29 | *p1 = v1; 30 | std::cout << "Change v2 to equal v1:" << std::endl; 31 | std::cout << "p1 value: " << *p1 << std::endl; 32 | std::cout << "p1 address: " << p1 << std::endl; 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Chapter_03/exercise_24b.cpp: -------------------------------------------------------------------------------- 1 | // Redo the last exercise from § 3.3.3 (p. 105) using iterators. 2 | 3 | #include 4 | #include 5 | 6 | using std::cout; 7 | using std::cin; 8 | using std::endl; 9 | using std::vector; 10 | using std::cerr; 11 | 12 | int main() 13 | { 14 | cout << "Enter some numbers: "; 15 | int userInput; 16 | if (cin >> userInput) 17 | { 18 | vector userData {userInput}; 19 | while (cin >> userInput) 20 | { 21 | userData.push_back(userInput); 22 | } 23 | 24 | if (userData.size() > 1) 25 | { 26 | auto beg = userData.cbegin(); 27 | auto end = userData.cend() - 1; 28 | while (beg < end) 29 | { 30 | cout << *beg + *end << " "; 31 | ++beg; 32 | --end; 33 | } 34 | cout << endl; 35 | 36 | if (beg == end) 37 | { 38 | cout << "Middle value '" << *beg 39 | << "' has nothing to do." << endl; 40 | } 41 | 42 | return 0; 43 | } 44 | } 45 | cerr << endl << "Need at least two numbers." << endl; 46 | 47 | return -1; 48 | } 49 | -------------------------------------------------------------------------------- /Chapter_05/exercise_20.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to read a sequence of strings from the standard input 2 | // until the same word occurs twice in succession or all the words have 3 | // been read. Use a `while` loop to read the text one word at a time. 4 | // Use the `break` statement to terminate the loop if a word occurs twice 5 | // in succession. Print the word if it occurs twice in succession, or else 6 | // print a message saying that no word was repeated. 7 | 8 | #include 9 | #include 10 | 11 | using std::cin; 12 | using std::cout; 13 | using std::endl; 14 | using std::string; 15 | 16 | int main() 17 | { 18 | string userInput; 19 | string previousWord = ""; 20 | bool isRepeated = false; 21 | 22 | while (cin >> userInput) 23 | { 24 | if (previousWord == userInput) 25 | { 26 | isRepeated = true; 27 | break; 28 | } 29 | previousWord = userInput; 30 | } 31 | 32 | if (isRepeated) 33 | { 34 | cout << "'" << previousWord << "' " 35 | << "occurred twice in a row." << endl; 36 | } 37 | else 38 | { 39 | cout << "No words were repeated in succession." << endl; 40 | } 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Chapter_03/exercise_44a.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the programs from the previous exercises using a type alias 2 | // for the type of the loop control variables. 3 | 4 | #include 5 | 6 | using std::cout; 7 | using std::endl; 8 | 9 | int main() 10 | { 11 | // Dimensions of array 12 | constexpr size_t rowCount = 3; 13 | constexpr size_t colCount = 4; 14 | 15 | // Type alias 16 | using int_array = int[colCount]; 17 | 18 | int ia[rowCount][colCount]; 19 | 20 | // Fill ia (using type alias) 21 | auto count = 0; 22 | 23 | for (int_array& row : ia) 24 | { 25 | for (int& col : row) 26 | { 27 | col = count; 28 | ++count; 29 | } 30 | } 31 | // Initialisation code above is the same for all versions of this 32 | // exercise (pointer version includes the iterator header and using 33 | // declarations for begin and end). 34 | 35 | // Print output using range for loop (using type alias) 36 | cout << "Using 'range for' & type alias:" << endl; 37 | for (const int_array& row : ia) 38 | { 39 | for (int col : row) 40 | { 41 | cout << col << " "; 42 | } 43 | cout << endl; 44 | } 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /Chapter_04/exercise_28.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to print the size of each of the built-in types. 2 | 3 | #include 4 | 5 | using std::cout; 6 | using std::endl; 7 | 8 | int main() 9 | { 10 | cout << "Size of nullptr: " << sizeof(nullptr) << " byte(s)." << endl 11 | << "Size of bool: " << sizeof(bool) << " byte(s)." << endl 12 | << "Size of char: " << sizeof(char) << " byte(s)." << endl 13 | << "Size of wchar_t: " << sizeof(wchar_t) << " byte(s)." << endl 14 | << "Size of char16_t: " << sizeof(char16_t) << " byte(s)." << endl 15 | << "Size of char32_t: " << sizeof(char32_t) << " byte(s)." << endl 16 | << "Size of short: " << sizeof(short) << " byte(s)." << endl 17 | << "Size of int: " << sizeof(int) << " byte(s)." << endl 18 | << "Size of long: " << sizeof(long) << " byte(s)." << endl 19 | << "Size of long long: " << sizeof(long long) << " byte(s)." << endl 20 | << "Size of float: " << sizeof(float) << " byte(s)." << endl 21 | << "Size of double: " << sizeof(double) << " byte(s)." << endl 22 | << "Size of long double: " << sizeof(long double) << " byte(s)." << endl; 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Chapter_03/exercise_04a.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to read two strings and report whether the strings 2 | // are equal. If not, report which of the two is larger. Now, change 3 | // the program to report whether the strings have the same length, and 4 | // if not, report which is longer. 5 | 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::cin; 11 | using std::endl; 12 | using std::string; 13 | 14 | int main() 15 | { 16 | cout << "Enter two strings to compare: "; 17 | string firstString; 18 | string secondString; 19 | if (cin >> firstString >> secondString) 20 | { 21 | if (firstString == secondString) 22 | { 23 | cout << "Strings are equal." << endl; 24 | } 25 | else 26 | { 27 | string result = "larger"; 28 | if (firstString < secondString) 29 | { 30 | result = "smaller"; 31 | } 32 | 33 | cout << "'" << firstString << "' is " << result 34 | << " than '" << secondString << "'" << endl; 35 | } 36 | } 37 | else 38 | { 39 | std::cerr << endl << "Please enter two strings." << endl; 40 | 41 | return -1; 42 | 43 | } 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /Chapter_03/exercise_20a.cpp: -------------------------------------------------------------------------------- 1 | // Read a set of integers into a vector. Print the sum of each pair of 2 | // adjacent elements. Change your program so that it prints the sum of 3 | // the first and last elements, followed by the sum of the second and 4 | // second-to-last, and so on. 5 | 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::cin; 11 | using std::endl; 12 | using std::cerr; 13 | using std::vector; 14 | 15 | int main() 16 | { 17 | cout << "Enter some numbers: "; 18 | int userInput; 19 | if (cin >> userInput) 20 | { 21 | vector userData{userInput}; 22 | while (cin >> userInput) 23 | { 24 | userData.push_back(userInput); 25 | } 26 | 27 | vector::size_type size = userData.size(); 28 | if (size >= 2) 29 | { 30 | for (vector::size_type i = 0; i < size - 1; ++i) 31 | { 32 | cout << userData[i] + userData[i + 1] << " "; 33 | } 34 | cout << endl; 35 | 36 | return 0; 37 | } 38 | else 39 | { 40 | cerr << "Need at least two numbers." << endl; 41 | 42 | return -1; 43 | } 44 | } 45 | else 46 | { 47 | cerr << endl << "No input!" << endl; 48 | 49 | return -1; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Chapter_01/exercise_25.cpp: -------------------------------------------------------------------------------- 1 | // Using the Sales_item.h header from the website, compile and execute the 2 | // bookstore program presented in this section. 3 | 4 | #include 5 | #include "../include/Sales_item.h" 6 | 7 | int main() 8 | { 9 | Sales_item total; // variable to hold data for the next transaction 10 | // read the first transaction and ensure that there is data to process 11 | if (std::cin >> total) 12 | { 13 | Sales_item trans; // variable to hold the running sum 14 | // read and process the remaining transactions 15 | while (std::cin >> trans) 16 | { 17 | // if we're still processing the same book 18 | if (total.isbn() == trans.isbn()) 19 | { 20 | total += trans; // update the running total 21 | } 22 | else 23 | { 24 | // print results for the previous book 25 | std::cout << total << std::endl; 26 | total = trans; // total now refers to the next book 27 | } 28 | } 29 | std::cout << total << std::endl; // print the last transaction 30 | } 31 | else 32 | { 33 | // no input! warn the user 34 | std::cerr << "No data?!" << std::endl; 35 | 36 | return -1; // indicate error 37 | } 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /include/Screen_v2.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SCREEN_V2_HPP 2 | #define SCREEN_V2_HPP 3 | 4 | #include 5 | 6 | class Screen 7 | { 8 | public: 9 | typedef std::string::size_type position; 10 | Screen() = default; 11 | Screen(position height, position width) 12 | : m_height(height) 13 | , m_width(width) 14 | , m_contents(height * width, ' ') 15 | {} 16 | Screen(position height, position width, char value) 17 | : m_height(height) 18 | , m_width(width) 19 | , m_contents(height * width, value) 20 | {} 21 | 22 | char get() const 23 | { 24 | return m_contents[m_cursor]; 25 | } 26 | 27 | position len() const 28 | { 29 | return m_contents.length(); 30 | } 31 | 32 | char get(position height, position width) const; 33 | 34 | Screen& move(position row, position column); 35 | 36 | private: 37 | position m_cursor = 0; 38 | position m_height = 0; 39 | position m_width = 0; 40 | std::string m_contents; 41 | }; // Screen class 42 | 43 | #endif // SCREEN_V2_HPP 44 | 45 | inline 46 | Screen& Screen::move(position row, position column) 47 | { 48 | m_cursor = (row * m_width) + column; 49 | return *this; 50 | } 51 | 52 | inline 53 | char Screen::get(position row, position column) const 54 | { 55 | return m_contents[(row * m_width) + column]; 56 | } 57 | -------------------------------------------------------------------------------- /Chapter_05/exercise_09.cpp: -------------------------------------------------------------------------------- 1 | // Write a program using a series of `if` statements to count the number 2 | // of vowels in text read from `cin`. 3 | 4 | #include 5 | 6 | using std::cout; 7 | using std::cin; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | int aCount = 0; 13 | int eCount = 0; 14 | int iCount = 0; 15 | int oCount = 0; 16 | int uCount = 0; 17 | int totalCount = 0; 18 | char charInput; 19 | while (cin >> charInput) 20 | { 21 | ++totalCount; 22 | if (charInput == 'a') 23 | { 24 | ++aCount; 25 | } 26 | else if (charInput == 'e') 27 | { 28 | ++eCount; 29 | } 30 | else if (charInput == 'i') 31 | { 32 | ++iCount; 33 | } 34 | else if (charInput == 'o') 35 | { 36 | ++oCount; 37 | } 38 | else if (charInput == 'u') 39 | { 40 | ++uCount; 41 | } 42 | } 43 | cout << endl << "Processed " << totalCount << " characters." << endl; 44 | 45 | cout << "Number of vowel a: \t" << aCount << endl 46 | << "Number of vowel e: \t" << eCount << endl 47 | << "Number of vowel i: \t" << iCount << endl 48 | << "Number of vowel o: \t" << oCount << endl 49 | << "Number of vowel u: \t" << uCount << endl; 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /include/Person_v5.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PERSON_V5_HPP 2 | #define PERSON_V5_HPP 3 | 4 | #include 5 | #include 6 | 7 | struct Person 8 | { 9 | friend std::istream& read(std::istream& input, Person& person); 10 | friend std::ostream& print(std::ostream& output, const Person& person); 11 | 12 | public: 13 | Person() = default; 14 | 15 | Person(const std::string name, const std::string address) 16 | : name(name) 17 | , address(address) 18 | { } 19 | 20 | Person(std::istream& input) 21 | { 22 | read(input, *this); 23 | } 24 | std::string get_name() const; 25 | std::string get_address() const; 26 | 27 | private: 28 | std::string name; 29 | std::string address; 30 | }; // Person Class 31 | 32 | std::string Person::get_name() const 33 | { 34 | return this->name; 35 | } 36 | 37 | std::string Person::get_address() const 38 | { 39 | return this->address; 40 | } 41 | 42 | std::istream& read(std::istream& input, Person& person) 43 | { 44 | // Grab data one line at a time (to allow for spaces) 45 | std::getline(input, person.name); 46 | std::getline(input, person.address); 47 | return input; 48 | } 49 | 50 | std::ostream& print(std::ostream& output, const Person& person) 51 | { 52 | output << person.name << " " << person.address; 53 | return output; 54 | } 55 | 56 | #endif // PERSON_V5_HPP 57 | -------------------------------------------------------------------------------- /Chapter_03/exercise_44b.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the programs from the previous exercises using a type alias 2 | // for the type of the loop control variables. 3 | 4 | #include 5 | 6 | using std::cout; 7 | using std::endl; 8 | 9 | int main() 10 | { 11 | // Dimensions of array 12 | constexpr size_t rowCount = 3; 13 | constexpr size_t colCount = 4; 14 | 15 | // Type alias 16 | using int_array = int[colCount]; 17 | 18 | int ia[rowCount][colCount]; 19 | 20 | // Fill ia (using type alias) 21 | auto count = 0; 22 | 23 | for (int_array &row : ia) 24 | { 25 | for (int &col : row) 26 | { 27 | col = count; 28 | ++count; 29 | } 30 | } 31 | // Initialisation code above is the same for all versions of this 32 | // exercise (pointer version includes the iterator header and using 33 | // declarations for begin and end). 34 | 35 | // Print output using subscript (using type alias) 36 | cout << "Using 'subscript' using type alias:" << endl; 37 | 38 | // Type alias 39 | using current_row = size_t; 40 | using current_col = size_t; 41 | 42 | for (current_row i = 0; i != rowCount; ++i) 43 | { 44 | for (current_col j = 0; j != colCount; ++j) 45 | { 46 | cout << ia[i][j] << " "; 47 | } 48 | cout << endl; 49 | } 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /Chapter_03/exercise_04b.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to read two strings and report whether the strings 2 | // are equal. If not, report which of the two is larger. Now, change 3 | // the program to report whether the strings have the same length, and 4 | // if not, report which is longer. 5 | 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::cin; 11 | using std::endl; 12 | using std::string; 13 | 14 | int main() 15 | { 16 | cout << "Enter two strings to compare: "; 17 | string firstString; 18 | string secondString; 19 | if (cin >> firstString >> secondString) 20 | { 21 | auto firstStringSize = firstString.size(); 22 | auto secondStringSize = secondString.size(); 23 | if (firstStringSize == secondStringSize) 24 | { 25 | cout << "Strings have the same length." << endl; 26 | } 27 | else 28 | { 29 | string result = "longer"; 30 | if (firstStringSize < secondStringSize) 31 | { 32 | result = "shorter"; 33 | } 34 | 35 | cout << "'" << firstString << "' is " << result 36 | << " than '" << secondString << "'" << endl; 37 | } 38 | } 39 | else 40 | { 41 | std::cerr << endl << "Please enter two strings." << endl; 42 | 43 | return -1; 44 | 45 | } 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /data/lorem_ipsum.txt: -------------------------------------------------------------------------------- 1 | rem ipsum dolor sit amet, nonumes intellegam ea est. Vel impetus equidem comprehensam an, tollit praesent cum no. Ad has melius admodum lobortis, erat urbanitas eu vim. His minim consequat te, veniam tempor sensibus an vim. Omnes dolorem pri an. 2 | 3 | Cum et purto percipit assentior. Insolens gubergren cum ei. In qui vide tollit noluisse. In accommodare mediocritatem nam, choro abhorreant nec ex. Ad vis tempor offendit, id nam eruditi probatus urbanitas, qui ei hinc molestiae. 4 | 5 | Usu ad simul dolorum euripidis, mei eu maiorum aliquando. Mentitum salutandi mea eu. Has an verear liberavisse. Harum nonumes cu ius. 6 | 7 | Magna porro nusquam ea per, nominati reprehendunt signiferumque no est, id vel odio discere delicatissimi. Ut duo verear facilis albucius, nam ex saperet expetendis. Vel dicant maiorum convenire no, cu vitae meliore commune vis. Libris primis eum et. Eam quem labitur ut. Usu brute detraxit intellegebat ex, usu sale ludus an. Est regione bonorum eligendi ex, ne eum magna labore reprehendunt. 8 | 9 | No eos altera timeam perfecto, antiopam deterruisset at nec. Vim ex etiam affert, has ea postea molestiae dissentiet, audiam principes in vix. No his agam erant. Id has porro molestie interesset, mutat aperiam vis at. Sit et autem deserunt, habemus senserit ne sea. 10 | col1 col2 col3 11 | row1 data1 data2 data3 12 | row2 data4 data5 data6 13 | row3 data7 data8 data9 14 | flfifl 15 | -------------------------------------------------------------------------------- /Chapter_03/exercise_17.cpp: -------------------------------------------------------------------------------- 1 | // Read a sequence of words from cin and store the values in a vector. 2 | // After you've read all the words, process the vector and change each 3 | // word to uppercase. Print the transformed elements, eight words to a line. 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::cin; 11 | using std::endl; 12 | using std::string; 13 | using std::vector; 14 | using std::cerr; 15 | 16 | 17 | int main() 18 | { 19 | cout << "Enter some words: "; 20 | string userInput; 21 | if (cin >> userInput) 22 | { 23 | vector collectedData{userInput}; 24 | while (cin >> userInput) 25 | { 26 | collectedData.push_back(userInput); 27 | } 28 | for (auto& word : collectedData) 29 | { 30 | for (auto& letter : word) 31 | { 32 | letter = toupper(letter); 33 | } 34 | } 35 | for (vector::size_type i = 0; 36 | i < collectedData.size(); ++i) 37 | { 38 | if (i > 0 && i % 8 == 0) 39 | { 40 | cout << endl; 41 | } 42 | 43 | cout << collectedData[i] << " "; 44 | } 45 | cout << endl; 46 | 47 | return 0; 48 | } 49 | else 50 | { 51 | cerr << endl << "No input!" << endl; 52 | 53 | return -1; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Chapter_03/exercise_43a.cpp: -------------------------------------------------------------------------------- 1 | // Write three different versions of a program to print the elements 2 | // of ia. One version should use a range for to manage the iteration, 3 | // the other two should use an ordinary for loop in one case using 4 | // subscripts and in the other using pointers. In all three programs 5 | // write all the types directly. That is, do not use the type alias, 6 | // auto, or decltype to simplify code. 7 | 8 | #include 9 | 10 | using std::cout; 11 | using std::endl; 12 | 13 | int main() 14 | { 15 | // Dimensions of array 16 | constexpr size_t rowCount = 3; 17 | constexpr size_t colCount = 4; 18 | 19 | int ia[rowCount][colCount]; 20 | 21 | // Fill ia (no auto) 22 | size_t count = 0; 23 | 24 | for (int(& row)[4] : ia) 25 | { 26 | for (int& col : row) 27 | { 28 | col = count; 29 | ++count; 30 | } 31 | } 32 | // Initialisation code above is the same for all versions of this 33 | // exercise (pointer version includes the iterator header and using 34 | // declarations for begin and end). 35 | 36 | // Print output using range for loop (no auto) 37 | cout << "Using 'range for':" << endl; 38 | for (const int(& row)[rowCount + 1] : ia) 39 | { 40 | for (int col : row) 41 | { 42 | cout << col << " "; 43 | } 44 | cout << endl; 45 | } 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /Chapter_05/exercise_25.cpp: -------------------------------------------------------------------------------- 1 | // Revise your program from the previous exercise to use a `try` block to 2 | // `catch` the exception. The `catch` clause should print a message to the 3 | // user and ask them to supply a new number and repeat the code inside the 4 | // `try` 5 | 6 | #include 7 | #include 8 | 9 | using std::cin; 10 | using std::cout; 11 | using std::endl; 12 | using std::cerr; 13 | 14 | int main() 15 | { 16 | int intX; 17 | int intY; 18 | cout << "Integer division: x/y" << endl 19 | << "Enter values for 'x' and 'y': "; 20 | while (cin >> intX >> intY) 21 | { 22 | try 23 | { 24 | if (intY == 0) 25 | { 26 | throw std::logic_error("Divide-by-zero exception."); 27 | } 28 | cout << intX << "/" << intY << " = " 29 | << intX / intY << endl; 30 | return 0; 31 | } 32 | catch (std::logic_error err) 33 | { 34 | cout << err.what() 35 | << " Try again? [y/n]: "; 36 | char response; 37 | cin >> response; 38 | if (!cin || response == 'n') 39 | { 40 | break; 41 | } 42 | cout << "Enter new values for 'x' and 'y': " << endl; 43 | } 44 | } 45 | cerr << endl << "Must supply two valid integers!" << endl; 46 | 47 | return -1; 48 | } 49 | -------------------------------------------------------------------------------- /Chapter_03/exercise_43b.cpp: -------------------------------------------------------------------------------- 1 | // Write three different versions of a program to print the elements 2 | // of ia. One version should use a range for to manage the iteration, 3 | // the other two should use an ordinary for loop in one case using 4 | // subscripts and in the other using pointers. In all three programs 5 | // write all the types directly. That is, do not use the type alias, 6 | // auto, or decltype to simplify code. 7 | 8 | #include 9 | 10 | using std::cout; 11 | using std::endl; 12 | 13 | int main() 14 | { 15 | // Dimensions of array 16 | constexpr size_t rowCount = 3; 17 | constexpr size_t colCount = 4; 18 | 19 | int ia[rowCount][colCount]; 20 | 21 | // Fill ia (no auto) 22 | size_t count = 0; 23 | 24 | for (int(& row)[4] : ia) 25 | { 26 | for (int& col : row) 27 | { 28 | col = count; 29 | ++count; 30 | } 31 | } 32 | // Initialisation code above is the same for all versions of this 33 | // exercise (pointer version includes the iterator header and using 34 | // declarations for begin and end). 35 | 36 | // Print output using subscript (no auto) 37 | cout << "Using 'subscript':" << endl; 38 | for (size_t i = 0; i != rowCount; ++i) 39 | { 40 | for (int j = 0; j != colCount; ++j) 41 | { 42 | cout << ia[i][j] << " "; 43 | } 44 | cout << endl; 45 | } 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /Chapter_07/exercise_03.cpp: -------------------------------------------------------------------------------- 1 | // Revise your transaction-processing program from § 7.1.1 (p. 256) to use 2 | // these members 3 | 4 | #include 5 | #include 6 | #include "../include/Sales_data_v2.hpp" 7 | 8 | using std::cin; 9 | using std::cout; 10 | using std::endl; 11 | using std::string; 12 | 13 | int main() 14 | { 15 | Sales_data total; 16 | if (cin >> total.bookNo 17 | >> total.units_sold 18 | >> total.revenue) 19 | { 20 | Sales_data transaction; 21 | while (cin >> transaction.bookNo 22 | >> transaction.units_sold 23 | >> transaction.revenue) 24 | { 25 | if (total.isbn() == transaction.isbn()) 26 | { 27 | total.combine(transaction); 28 | } 29 | else 30 | { 31 | cout << "ISBN: " << total.bookNo << endl 32 | << "Units sold: " << total.units_sold << endl 33 | << "Total revenue: " << total.revenue << endl 34 | << endl; 35 | total = transaction; 36 | } 37 | } 38 | cout << "ISBN: " << total.bookNo << endl 39 | << "Units sold: " << total.units_sold << endl 40 | << "Total revenue: " << total.revenue << endl; 41 | } 42 | else 43 | { 44 | std::cerr << "No data?!" << endl; 45 | 46 | return -1; 47 | } 48 | 49 | return 0; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /Chapter_03/exercise_22.cpp: -------------------------------------------------------------------------------- 1 | // Revise the loop that printed the first paragraph in text to instead 2 | // change the elements in text that correspond to the first paragraph 3 | // to all uppercse. After you've updated text, print its contents. 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::cin; 11 | using std::endl; 12 | using std::string; 13 | using std::vector; 14 | 15 | int main() 16 | { 17 | vector text; 18 | text.push_back("This is the first paragraph."); 19 | text.push_back("This is still part of the first paragraph."); 20 | text.push_back(""); 21 | text.push_back("This is the second paragraph."); 22 | text.push_back(""); 23 | text.push_back("This is the third paragraph."); 24 | 25 | // Iterate over the text vector until we reach an empty element 26 | // or the end of the vector 27 | for (auto textIter = text.begin(); 28 | textIter != text.end() && !textIter->empty(); ++textIter) 29 | { 30 | // iterate over the string within the vector and change each 31 | // character to upper case 32 | for (auto strIter = textIter->begin(); 33 | strIter != textIter->end(); ++strIter) 34 | { 35 | *strIter = toupper(*strIter); 36 | } 37 | } 38 | // Print the results 39 | for (auto textIter = text.cbegin(); 40 | textIter != text.cend(); ++textIter) 41 | { 42 | cout << *textIter << endl; 43 | } 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /include/Person_v4.hpp: -------------------------------------------------------------------------------- 1 | // Provide operations in your Person class to return the name and address. 2 | // Should these functions be const? Explain your choice. 3 | 4 | #ifndef PERSON_V4_HPP 5 | #define PERSON_V4_HPP 6 | 7 | #include 8 | #include 9 | 10 | // Forward declaration 11 | struct Person; 12 | std::istream& read(std::istream& input, Person& person); 13 | std::ostream& print(std::ostream& output, const Person& person); 14 | 15 | struct Person 16 | { 17 | Person() = default; 18 | 19 | Person(const std::string name, const std::string address) 20 | : name(name) 21 | , address(address) 22 | { } 23 | 24 | Person(std::istream& input) 25 | { 26 | read(input, *this); 27 | } 28 | 29 | std::string name; 30 | std::string address; 31 | std::string get_name() const; 32 | std::string get_address() const; 33 | }; // Person Class 34 | 35 | std::string Person::get_name() const 36 | { 37 | return this->name; 38 | } 39 | 40 | std::string Person::get_address() const 41 | { 42 | return this->address; 43 | } 44 | 45 | std::istream& read(std::istream& input, Person& person) 46 | { 47 | // Grab data one line at a time (to allow for spaces) 48 | std::getline(input, person.name); 49 | std::getline(input, person.address); 50 | return input; 51 | } 52 | 53 | std::ostream& print(std::ostream& output, const Person& person) 54 | { 55 | output << person.name << " " << person.address; 56 | return output; 57 | } 58 | 59 | #endif // PERSON_V4_HPP 60 | -------------------------------------------------------------------------------- /Chapter_03/exercise_43c.cpp: -------------------------------------------------------------------------------- 1 | // Write three different versions of a program to print the elements 2 | // of ia. One version should use a range for to manage the iteration, 3 | // the other two should use an ordinary for loop in one case using 4 | // subscripts and in the other using pointers. In all three programs 5 | // write all the types directly. That is, do not use the type alias, 6 | // auto, or decltype to simplify code. 7 | 8 | #include 9 | #include 10 | 11 | using std::cout; 12 | using std::endl; 13 | using std::begin; 14 | using std::end; 15 | 16 | int main() 17 | { 18 | // Dimensions of array 19 | constexpr size_t rowCount = 3; 20 | constexpr size_t colCount = 4; 21 | 22 | int ia[rowCount][colCount]; 23 | 24 | // Fill ia (no auto) 25 | size_t count = 0; 26 | 27 | for (int(&row)[4] : ia) 28 | { 29 | for (int& col : row) 30 | { 31 | col = count; 32 | ++count; 33 | } 34 | } 35 | // Initialisation code above is the same for all versions of this 36 | // exercise (pointer version includes the iterator header and using 37 | // declarations for begin and end). 38 | 39 | // Print output using pointers (no auto) 40 | cout << "Using 'pointers':" << endl; 41 | for (int(*p)[colCount] = begin(ia); p != end(ia); ++p) 42 | { 43 | for (int* q = begin(*p); q != end(*p); ++q) 44 | { 45 | cout << *q << " "; 46 | } 47 | cout << endl; 48 | } 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /Chapter_03/exercise_44c.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the programs from the previous exercises using a type alias 2 | // for the type of the loop control variables. 3 | 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::endl; 9 | using std::begin; 10 | using std::end; 11 | 12 | int main() 13 | { 14 | // Dimensions of array 15 | constexpr size_t rowCount = 3; 16 | constexpr size_t colCount = 4; 17 | 18 | // Type alias 19 | using int_array = int[colCount]; 20 | 21 | int ia[rowCount][colCount]; 22 | 23 | // Fill ia (using type alias) 24 | auto count = 0; 25 | 26 | for (int_array& row : ia) 27 | { 28 | for (int& col : row) 29 | { 30 | col = count; 31 | ++count; 32 | } 33 | } 34 | // Initialisation code above is the same for all versions of this 35 | // exercise (pointer version includes the iterator header and using 36 | // declarations for begin and end). 37 | 38 | // Print output using pointers (using type alias) 39 | cout << "Using 'pointers' & type alias:" << endl; 40 | 41 | // Type alias 42 | using row_pointer = int[colCount]; 43 | using col_pointer = int; 44 | 45 | // for (int(*p)[rowCount + 1] = begin(ia); p != end(ia); ++p) 46 | for (row_pointer* p = begin(ia); p != end(ia); ++p) 47 | { 48 | for (col_pointer* q = begin(*p); q != end(*p); ++q) 49 | { 50 | cout << *q << " "; 51 | } 52 | cout << endl; 53 | } 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /Chapter_03/exercise_20b.cpp: -------------------------------------------------------------------------------- 1 | // Read a set of integers into a vector. Print the sum of each pair of 2 | // adjacent elements. Change your program so that it prints the sum of 3 | // the first and last elements, followed by the sum of the second and 4 | // second-to-last, and so on. 5 | 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::cin; 11 | using std::endl; 12 | using std::cerr; 13 | using std::vector; 14 | 15 | int main() 16 | { 17 | cout << "Enter some numbers: "; 18 | int userInput; 19 | if (cin >> userInput) 20 | { 21 | vector userData{userInput}; 22 | while (cin >> userInput) 23 | { 24 | userData.push_back(userInput); 25 | } 26 | 27 | vector::size_type size = userData.size(); 28 | if (size >= 2) 29 | { 30 | for (vector::size_type i = 0; i < size / 2; ++i) 31 | { 32 | cout << userData[i] + userData[size - (i + 1)] << " "; 33 | } 34 | cout << endl; 35 | 36 | if (size % 2 != 0) 37 | { 38 | cout << "Middle value '" << userData[size / 2] 39 | << "' has nothing to do." << endl; 40 | } 41 | 42 | return 0; 43 | } 44 | else 45 | { 46 | cerr << "Need at least two numbers." << endl; 47 | 48 | return -1; 49 | } 50 | } 51 | else 52 | { 53 | cerr << endl << "No input!" << endl; 54 | 55 | return -1; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Chapter_05/exercise_14.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to read strings from standard input 2 | // looking for duplicated words. The program should find places in the input 3 | // where one word is followed immediately by itself. Keep track of the largest 4 | // number of times a single repetition occurs and which word is repeated. Print 5 | // the maximum number of duplicates, or else print a message saying that no 6 | // word was repeated. For example, if the input is 7 | // `how now now now brown cow cow` 8 | // the output should indicate that the word `now` occurred three times. 9 | 10 | #include 11 | #include 12 | 13 | using std::cin; 14 | using std::cout; 15 | using std::endl; 16 | using std::string; 17 | 18 | int main() 19 | { 20 | string maxWord = ""; 21 | int maxCount = 0; 22 | string previousWord = ""; 23 | int currentCount = 0; 24 | string userInput; 25 | 26 | while (cin >> userInput) 27 | { 28 | if (userInput == previousWord) 29 | { 30 | ++currentCount; 31 | if (currentCount > maxCount) 32 | { 33 | maxCount = currentCount; 34 | maxWord = userInput; 35 | } 36 | } 37 | else 38 | { 39 | currentCount = 1; 40 | } 41 | previousWord = userInput; 42 | } 43 | if (maxCount < 2) 44 | { 45 | cout << "No matching consecutive words!" << endl; 46 | } 47 | else 48 | { 49 | cout << "'" << maxWord << "' occurred " 50 | << maxCount << " times." << endl; 51 | } 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /Chapter_07/exercise_01.cpp: -------------------------------------------------------------------------------- 1 | // Write a version of the transaction-processing program from § 1.6 (p. 24) 2 | // using the Sales_data class you defined for the exercises in § 2.6.1 (p. 72). 3 | 4 | #include 5 | #include 6 | #include "../include/Sales_data.hpp" 7 | 8 | using std::cin; 9 | using std::cout; 10 | using std::endl; 11 | using std::string; 12 | 13 | int main() 14 | { 15 | Sales_data total; 16 | if (cin >> total.bookNo 17 | >> total.units_sold 18 | >> total.revenue) 19 | { 20 | Sales_data transaction; 21 | while (cin >> transaction.bookNo 22 | >> transaction.units_sold 23 | >> transaction.revenue) 24 | { 25 | if (total.bookNo == transaction.bookNo) 26 | { 27 | total.units_sold += transaction.units_sold; 28 | total.revenue += transaction.revenue; 29 | } 30 | else 31 | { 32 | cout << "ISBN: " << total.bookNo << endl 33 | << "Units sold: " << total.units_sold << endl 34 | << "Total revenue: " << total.revenue << endl 35 | << endl; 36 | total = transaction; 37 | } 38 | } 39 | cout << "ISBN: " << total.bookNo << endl 40 | << "Units sold: " << total.units_sold << endl 41 | << "Total revenue: " << total.revenue << endl; 42 | } 43 | else 44 | { 45 | std::cerr << "No data?!" << endl; 46 | 47 | return -1; 48 | } 49 | 50 | return 0; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /Chapter_06/exercise_37.cpp: -------------------------------------------------------------------------------- 1 | // Write three additional declarations for the function in the previous 2 | // exercise. One should use a type alias, one should use a trailing return, 3 | // and the third should use decltype. Which form do you prefer and why? 4 | 5 | #include 6 | #include 7 | 8 | using std::cout; 9 | using std::endl; 10 | using std::string; 11 | 12 | // Array for testing 13 | string firstTenChars[10] = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"}; 14 | 15 | // using statement for type alias version 16 | using tenStrings = string[10]; 17 | 18 | // Function declarations 19 | tenStrings& getStrings1(tenStrings& strArray); 20 | auto getStrings2(tenStrings& strArray) -> string(&)[10]; 21 | decltype(firstTenChars)& getStrings3(tenStrings& strArray); 22 | 23 | // Fleshed out, but kinda useless functions - just for testing 24 | tenStrings& getStrings1(tenStrings& strArray) 25 | { 26 | return strArray; 27 | } 28 | 29 | // Using trailing return type 30 | auto getStrings2(tenStrings& strArray) -> string(&)[10] 31 | { 32 | return strArray; 33 | } 34 | 35 | // Using decltype 36 | decltype(firstTenChars)& getStrings3(tenStrings& strArray) 37 | { 38 | return strArray; 39 | } 40 | 41 | void printArray(tenStrings& strArray) 42 | { 43 | for (auto s : strArray) 44 | { 45 | cout << s << " "; 46 | } 47 | cout << endl; 48 | } 49 | 50 | int main() 51 | { 52 | // Print results of each function 53 | printArray(getStrings1(firstTenChars)); 54 | printArray(getStrings2(firstTenChars)); 55 | printArray(getStrings3(firstTenChars)); 56 | 57 | return 0; 58 | } 59 | 60 | -------------------------------------------------------------------------------- /Chapter_05/exercise_21.cpp: -------------------------------------------------------------------------------- 1 | // Revise the program from the exercise in § 5.5.1 (p. 191) so that it 2 | // looks only for duplicated words that start with an uppercase letter. 3 | 4 | #include 5 | #include 6 | 7 | using std::cin; 8 | using std::cout; 9 | using std::endl; 10 | using std::string; 11 | 12 | int main() 13 | { 14 | string userInput; 15 | string previousWord = ""; 16 | bool isRepeated = false; 17 | 18 | while (cin >> userInput) 19 | { 20 | if (!isupper(userInput[0])) 21 | { 22 | previousWord = userInput; 23 | continue; 24 | } 25 | if (previousWord == userInput) 26 | { 27 | isRepeated = true; 28 | break; 29 | } 30 | else 31 | { 32 | previousWord = userInput; 33 | } 34 | 35 | // Commented code would probably be a better solution 36 | // but since this topic is on the `continue` statement 37 | // we'll use that instead. 38 | // 39 | // if (isupper(userInput[0]) && previousWord == userInput) 40 | // { 41 | // isRepeated = true; 42 | // break; 43 | // } 44 | // else 45 | // { 46 | // previousWord = userInput; 47 | // } 48 | 49 | } 50 | if (isRepeated) 51 | { 52 | cout << "'" << previousWord << "' " 53 | << "occurred twice in a row." << endl; 54 | } 55 | else 56 | { 57 | cout << "No words with capitalised first letters were repeated in succession." 58 | << endl; 59 | } 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /Chapter_05/exercise_10a.cpp: -------------------------------------------------------------------------------- 1 | // There is one problem with our vowel-counting program as we've 2 | // implemented it: It doesn't count capital letters as vowels. 3 | // Write a program that counts both lower and uppercase letters 4 | // as the appropriate vowel--that is, ypur program should count 5 | // both `'a'` and `'A'` as part of `aCnt`, and so forth. 6 | 7 | // Option 1: use `tolower()` for comparison (minimal change to code) 8 | 9 | #include 10 | 11 | using std::cout; 12 | using std::cin; 13 | using std::endl; 14 | 15 | int main() 16 | { 17 | int aCount = 0; 18 | int eCount = 0; 19 | int iCount = 0; 20 | int oCount = 0; 21 | int uCount = 0; 22 | int totalCount = 0; 23 | char charInput; 24 | while (cin >> charInput) 25 | { 26 | ++totalCount; 27 | if (tolower(charInput) == 'a') 28 | { 29 | ++aCount; 30 | } 31 | else if (tolower(charInput) == 'e') 32 | { 33 | ++eCount; 34 | } 35 | else if (tolower(charInput) == 'i') 36 | { 37 | ++iCount; 38 | } 39 | else if (tolower(charInput) == 'o') 40 | { 41 | ++oCount; 42 | } 43 | else if (tolower(charInput) == 'u') 44 | { 45 | ++uCount; 46 | } 47 | } 48 | cout << endl << "Processed " << totalCount << " characters." << endl; 49 | 50 | cout << "Number of vowel a: \t" << aCount << endl 51 | << "Number of vowel e: \t" << eCount << endl 52 | << "Number of vowel i: \t" << iCount << endl 53 | << "Number of vowel o: \t" << oCount << endl 54 | << "Number of vowel u: \t" << uCount << endl; 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /include/Sales_data_v3.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SALES_DATA_V3_HPP 2 | #define SALES_DATA_V3_HPP 3 | 4 | #include 5 | #include 6 | 7 | struct Sales_data 8 | { 9 | std::string bookNo; 10 | unsigned units_sold = 0; 11 | double revenue = 0.0; 12 | std::string isbn() const; 13 | Sales_data& combine(const Sales_data& transaction); 14 | Sales_data add(const Sales_data& first_transaction, 15 | const Sales_data& second_transaction); 16 | }; // Sales_data class 17 | 18 | std::istream& read(std::istream& input, Sales_data& transaction); 19 | std::ostream& print(std::ostream& output, const Sales_data& transaction); 20 | 21 | std::string Sales_data::isbn() const 22 | { 23 | return this->bookNo; 24 | } 25 | 26 | Sales_data& Sales_data::combine(const Sales_data& transaction) 27 | { 28 | if (this->isbn() == transaction.isbn()) 29 | { 30 | this->units_sold += transaction.units_sold; 31 | this->revenue += transaction.revenue; 32 | } 33 | return *this; 34 | } 35 | 36 | Sales_data add(const Sales_data& first_transaction, const Sales_data& second_transaction) 37 | { 38 | Sales_data sum = first_transaction; 39 | sum.combine(second_transaction); 40 | return sum; 41 | } 42 | 43 | std::istream& read(std::istream& input, Sales_data& transaction) 44 | { 45 | double price = 0.0; 46 | input >> transaction.bookNo >> transaction.units_sold >> price; 47 | transaction.revenue = transaction.units_sold * price; 48 | return input; 49 | } 50 | 51 | std::ostream& print(std::ostream& output, const Sales_data& transaction) 52 | { 53 | output << transaction.isbn() << " " 54 | << transaction.units_sold << " " 55 | << transaction.revenue; 56 | return output; 57 | } 58 | 59 | #endif // SALES_DATA_V3_HPP 60 | -------------------------------------------------------------------------------- /Chapter_05/exercise_10b.cpp: -------------------------------------------------------------------------------- 1 | // There is one problem with our vowel-counting program as we've 2 | // implemented it: It doesn't count capital letters as vowels. 3 | // Write a program that counts both lower and uppercase letters 4 | // as the appropriate vowel--that is, ypur program should count 5 | // both `'a'` and `'A'` as part of `aCnt`, and so forth. 6 | 7 | // Option 2: rewrite to use a `switch` statement 8 | 9 | #include 10 | 11 | using std::cout; 12 | using std::cin; 13 | using std::endl; 14 | 15 | int main() 16 | { 17 | int aCount = 0; 18 | int eCount = 0; 19 | int iCount = 0; 20 | int oCount = 0; 21 | int uCount = 0; 22 | int totalCount = 0; 23 | char charInput; 24 | while (cin >> charInput) 25 | { 26 | ++totalCount; 27 | switch (charInput) 28 | { 29 | case 'a': 30 | case 'A': 31 | ++aCount; 32 | break; 33 | case 'e': 34 | case 'E': 35 | ++eCount; 36 | break; 37 | case 'i': 38 | case 'I': 39 | ++iCount; 40 | break; 41 | case 'o': 42 | case 'O': 43 | ++oCount; 44 | break; 45 | case 'u': 46 | case 'U': 47 | ++uCount; 48 | break; 49 | } 50 | } 51 | cout << endl << "Processed " << totalCount << " characters." << endl; 52 | 53 | cout << "Number of vowel a: \t" << aCount << endl 54 | << "Number of vowel e: \t" << eCount << endl 55 | << "Number of vowel i: \t" << iCount << endl 56 | << "Number of vowel o: \t" << oCount << endl 57 | << "Number of vowel u: \t" << uCount << endl; 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /Chapter_02/exercise_34.cpp: -------------------------------------------------------------------------------- 1 | // Write a program containing the variables and assignments 2 | // from the previous exercise. Print the variables before and 3 | // after the assignments to check whether your predictions in the 4 | // previous exercise were correct. If not, study the examples until 5 | // you can convince yourself you know what led you to the wrong conclusion. 6 | 7 | #include 8 | 9 | int main() 10 | { 11 | int i = 0; 12 | int& r = i; 13 | 14 | const int ci = i; 15 | const int& cr = ci; 16 | 17 | auto a = r; // a is int = 0 18 | auto b = ci; // b is int = 0 19 | auto c = cr; // c is int = 0 20 | auto d = &i; // d is an int* = address of i = 0 21 | auto e = &ci; // e is a const int* = address of ci = 0 22 | auto& g = ci; // g is a const int& = reference to ci = 0 23 | 24 | std::cout << "Initial definitions:" << std::endl 25 | << "a = " << a << std::endl 26 | << "b = " << b << std::endl 27 | << "c = " << c << std::endl 28 | << "d = " << d << " (" << *d << ")" << std::endl 29 | << "e = " << e << " (" << *e << ")" << std::endl 30 | << "g = " << g << " (" << g << ")" << std::endl; 31 | 32 | a = 42; 33 | b = 42; 34 | c = 42; 35 | // d = 42; // Illegal must be dereferenced first 36 | *d = 42; 37 | // e = 42; // Illegal pointed to type is const int 38 | // g = 42; // Illegal referenced type is const int 39 | 40 | 41 | std::cout << "After assignment:" << std::endl 42 | << "a = " << a << std::endl 43 | << "b = " << b << std::endl 44 | << "c = " << c << std::endl 45 | << "d = " << d << " (" << *d << ")" << std::endl 46 | << "e = " << e << " (" << *e << ")" << std::endl 47 | << "g = " << g << " (" << g << ")" << std::endl; 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /Chapter_02/exercise_42a.cpp: -------------------------------------------------------------------------------- 1 | // Write your own version of the Sales_data.h header and use it to rewrite 2 | // the exercise from § 2.6.2 (p. 76). 3 | 4 | // Exercise 1.20 rewritten using Sales_data header. 5 | 6 | #include 7 | #include 8 | #include "../include/Sales_data.hpp" 9 | 10 | int main() 11 | { 12 | Sales_data transaction; 13 | 14 | // Read in the first transaction if there is one 15 | if (std::cin >> transaction.bookNo 16 | >> transaction.units_sold 17 | >> transaction.price) 18 | { 19 | transaction.revenue = transaction.price * transaction.units_sold; 20 | 21 | std::cout << "ISBN: " << transaction.bookNo << std::endl 22 | << "Units sold: " << transaction.units_sold << std::endl 23 | << "Price (each): " << transaction.price << std::endl 24 | << "Total revenue: " << transaction.revenue << std::endl 25 | << std::endl; 26 | 27 | // If there are more transactions, read and print them 28 | while (std::cin >> transaction.bookNo 29 | >> transaction.units_sold 30 | >> transaction.price) 31 | { 32 | transaction.revenue = transaction.price * transaction.units_sold; 33 | 34 | std::cout << "ISBN: " << transaction.bookNo << std::endl 35 | << "Units sold: " << transaction.units_sold << std::endl 36 | << "Price (each): " << transaction.price << std::endl 37 | << "Total revenue: " << transaction.revenue << std::endl 38 | << std::endl; 39 | } 40 | } 41 | else 42 | { 43 | std::cerr << "No data or incomplete transaction." << std::endl 44 | << "Supply data of the format: ISBN units_sold price_each." 45 | << std::endl; 46 | 47 | return -1; 48 | } 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /Chapter_06/exercise_23.cpp: -------------------------------------------------------------------------------- 1 | // Write your own versions of each of the print functions presented in 2 | // this section. Call each of these functions to print `i` and `j` 3 | // defined as follows: 4 | // int i = 0, j[2] = {0, 1}; 5 | 6 | #include 7 | #include 8 | 9 | using std::cin; 10 | using std::cout; 11 | using std::endl; 12 | using std::begin; 13 | using std::end; 14 | 15 | void divider() 16 | { 17 | cout << "----------------------------------------" << endl; 18 | } 19 | 20 | void print(const int* ival) 21 | { 22 | cout << "Output from function 'print(const int* ival)'" 23 | << endl; 24 | cout << *ival << endl; 25 | divider(); 26 | } 27 | 28 | void print(const char* cp) 29 | { 30 | cout << "Output from function 'print(const char* cp)'" 31 | << endl; 32 | if (cp) { 33 | while (*cp) { 34 | cout << *cp++ << endl; 35 | } 36 | } 37 | divider(); 38 | } 39 | 40 | void print(const int* beg, const int* end) 41 | { 42 | cout << "Output from function 'print(const int* beg, const int* end)'" 43 | << endl; 44 | while (beg != end) { 45 | cout << *beg++ << endl; 46 | } 47 | divider(); 48 | } 49 | 50 | void print(const int ia[], size_t size) 51 | { 52 | cout << "Output from function 'print(const int ia[], size_t size)'" 53 | << endl; 54 | for (size_t i = 0; i != size; ++i) { 55 | cout << ia[i] << endl; 56 | } 57 | divider(); 58 | } 59 | 60 | void print(int (&arr)[2]) 61 | { 62 | cout << "Output from function 'print(int (&arr)[2])'" 63 | << endl; 64 | for (auto elem : arr) { 65 | cout << elem << endl; 66 | } 67 | divider(); 68 | } 69 | 70 | int main() 71 | { 72 | int i = 0; 73 | int j[2] = { 0, 1 }; 74 | char c[3] = "ij"; 75 | 76 | print(&i); 77 | print(c); // variables i and j can't be used 78 | print(begin(j), end(j)); 79 | print(j, end(j) - begin(j)); 80 | print(j); 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /Chapter_03/exercise_01d.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the exercises from § 1.4.1 (p. 13) and § 2.6.2 (p. 76) 2 | // with appropriate using declarations. 3 | 4 | // Rewrite of a rewrite of exercise 1.20 5 | 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::cin; 11 | using std::endl; 12 | using std::string; 13 | using std::cerr; 14 | 15 | // My version of the Sales_data class 16 | // Included 'price' member since the incoming data contains it. 17 | struct Sales_data { 18 | string bookNo; 19 | unsigned units_sold = 0; 20 | double price = 0.0; 21 | double revenue = 0.0; 22 | }; 23 | 24 | int main() 25 | { 26 | Sales_data transaction; 27 | 28 | // Read in the first transaction if there is one 29 | if (cin >> transaction.bookNo 30 | >> transaction.units_sold 31 | >> transaction.price) 32 | { 33 | transaction.revenue = transaction.price * transaction.units_sold; 34 | 35 | cout << "ISBN: " << transaction.bookNo << endl 36 | << "Units sold: " << transaction.units_sold << endl 37 | << "Price (each): " << transaction.price << endl 38 | << "Total revenue: " << transaction.revenue << endl 39 | << endl; 40 | 41 | // If there are more transactions, read and print them 42 | while (cin >> transaction.bookNo 43 | >> transaction.units_sold 44 | >> transaction.price) 45 | { 46 | transaction.revenue = transaction.price * transaction.units_sold; 47 | 48 | cout << "ISBN: " << transaction.bookNo << endl 49 | << "Units sold: " << transaction.units_sold << endl 50 | << "Price (each): " << transaction.price << endl 51 | << "Total revenue: " << transaction.revenue << endl 52 | << endl; 53 | } 54 | } 55 | else 56 | { 57 | cerr << "No data or incomplete transaction" << endl 58 | << "Supply data of the format: ISBN units_sold price_each." 59 | << endl; 60 | 61 | return -1; 62 | } 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /include/Screen_v4.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SCREEN_V4_HPP 2 | #define SCREEN_V4_HPP 3 | 4 | #include 5 | 6 | class Screen 7 | { 8 | public: 9 | typedef std::string::size_type position; 10 | Screen() = default; 11 | Screen(position height, position width) 12 | : m_height(height) 13 | , m_width(width) 14 | , m_contents(height * width, ' ') 15 | {} 16 | Screen(position height, position width, char value) 17 | : m_height(height) 18 | , m_width(width) 19 | , m_contents(height * width, value) 20 | {} 21 | 22 | char get() const 23 | { 24 | return m_contents[m_cursor]; 25 | } 26 | 27 | position len() const 28 | { 29 | return m_contents.length(); 30 | } 31 | 32 | char get(position height, position width) const; 33 | 34 | Screen move(position row, position column); 35 | 36 | Screen set(char value); 37 | Screen set(position row, position column, char value); 38 | 39 | Screen display(std::ostream& output) 40 | { 41 | do_display(output); 42 | return *this; 43 | } 44 | 45 | const Screen display(std::ostream& output) const 46 | { 47 | do_display(output); 48 | return *this; 49 | } 50 | 51 | private: 52 | void do_display(std::ostream& output) const 53 | { 54 | output << m_contents; 55 | }; 56 | position m_cursor = 0; 57 | position m_height = 0; 58 | position m_width = 0; 59 | std::string m_contents; 60 | }; // Screen class 61 | 62 | #endif // SCREEN_V4_HPP 63 | 64 | inline 65 | Screen Screen::move(position row, position column) 66 | { 67 | m_cursor = (row * m_width) + column; 68 | return *this; 69 | } 70 | 71 | inline 72 | char Screen::get(position row, position column) const 73 | { 74 | return m_contents[(row * m_width) + column]; 75 | } 76 | 77 | inline 78 | Screen Screen::set(char value) 79 | { 80 | m_contents[m_cursor] = value; 81 | return *this; 82 | } 83 | 84 | inline 85 | Screen Screen::set(position row, position column, char value) 86 | { 87 | m_contents[row * m_width + column] = value; 88 | return *this; 89 | } 90 | -------------------------------------------------------------------------------- /include/Screen_v3.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SCREEN_V3_HPP 2 | #define SCREEN_V3_HPP 3 | 4 | #include 5 | 6 | class Screen 7 | { 8 | public: 9 | typedef std::string::size_type position; 10 | Screen() = default; 11 | Screen(position height, position width) 12 | : m_height(height) 13 | , m_width(width) 14 | , m_contents(height * width, ' ') 15 | {} 16 | Screen(position height, position width, char value) 17 | : m_height(height) 18 | , m_width(width) 19 | , m_contents(height * width, value) 20 | {} 21 | 22 | char get() const 23 | { 24 | return m_contents[m_cursor]; 25 | } 26 | 27 | position len() const 28 | { 29 | return m_contents.length(); 30 | } 31 | 32 | char get(position height, position width) const; 33 | 34 | Screen& move(position row, position column); 35 | 36 | Screen& set(char value); 37 | Screen& set(position row, position column, char value); 38 | 39 | Screen& display(std::ostream& output) 40 | { 41 | do_display(output); 42 | return *this; 43 | } 44 | 45 | const Screen& display(std::ostream& output) const 46 | { 47 | do_display(output); 48 | return *this; 49 | } 50 | 51 | private: 52 | void do_display(std::ostream& output) const 53 | { 54 | output << m_contents; 55 | }; 56 | position m_cursor = 0; 57 | position m_height = 0; 58 | position m_width = 0; 59 | std::string m_contents; 60 | }; // Screen class 61 | 62 | #endif // SCREEN_V3_HPP 63 | 64 | inline 65 | Screen& Screen::move(position row, position column) 66 | { 67 | m_cursor = (row * m_width) + column; 68 | return *this; 69 | } 70 | 71 | inline 72 | char Screen::get(position row, position column) const 73 | { 74 | return m_contents[(row * m_width) + column]; 75 | } 76 | 77 | inline 78 | Screen& Screen::set(char value) 79 | { 80 | m_contents[m_cursor] = value; 81 | return *this; 82 | } 83 | 84 | inline 85 | Screen& Screen::set(position row, position column, char value) 86 | { 87 | m_contents[row * m_width + column] = value; 88 | return *this; 89 | } 90 | -------------------------------------------------------------------------------- /Chapter_02/exercise_42d.cpp: -------------------------------------------------------------------------------- 1 | // Write your own version of the Sales_data.h header and use it to rewrite 2 | // the exercise from § 2.6.2 (p. 76). 3 | 4 | // Exercise 1.23 rewritten using Sales_data header. 5 | 6 | #include 7 | #include 8 | #include "../include/Sales_data.hpp" 9 | 10 | int main() 11 | { 12 | Sales_data currentTransaction; 13 | 14 | if (std::cin >> currentTransaction.bookNo 15 | >> currentTransaction.units_sold 16 | >> currentTransaction.price) 17 | { 18 | currentTransaction.revenue = currentTransaction.price * 19 | currentTransaction.units_sold; 20 | int transactionsForIsbn = 1; 21 | Sales_data nextTransaction; 22 | 23 | // Read in the rest of the transactions 24 | while (std::cin >> nextTransaction.bookNo 25 | >> nextTransaction.units_sold 26 | >> nextTransaction.price) 27 | { 28 | nextTransaction.revenue = nextTransaction.price * 29 | nextTransaction.units_sold; 30 | 31 | if (currentTransaction.bookNo == nextTransaction.bookNo) 32 | { 33 | ++transactionsForIsbn; 34 | } 35 | else 36 | { 37 | std::cout << transactionsForIsbn 38 | << " Transaction(s) for ISBN '" 39 | << currentTransaction.bookNo << "'" << std::endl; 40 | transactionsForIsbn = 1; 41 | currentTransaction.bookNo = nextTransaction.bookNo; 42 | currentTransaction.units_sold = nextTransaction.units_sold; 43 | currentTransaction.price = nextTransaction.price; 44 | currentTransaction.revenue = nextTransaction.revenue; 45 | } 46 | } 47 | } 48 | else 49 | { 50 | std::cerr << "No data or incomplete transaction" << std::endl 51 | << "Supply data of the format: ISBN units_sold price_each." 52 | << std::endl; 53 | 54 | return -1; 55 | } 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /Chapter_05/exercise_11.cpp: -------------------------------------------------------------------------------- 1 | // Modify our vowel-counting program so that it also counts the number 2 | // of blank spaces, tabs, and new lines read. 3 | 4 | #include 5 | 6 | using std::cout; 7 | using std::cin; 8 | using std::endl; 9 | using std::string; 10 | 11 | int main() 12 | { 13 | int aCount = 0; 14 | int eCount = 0; 15 | int iCount = 0; 16 | int oCount = 0; 17 | int uCount = 0; 18 | int spaceCount = 0; 19 | int tabCount = 0; 20 | int newLineCount = 0; 21 | int totalCount = 0; 22 | string userInput; 23 | while (getline(cin, userInput)) 24 | { 25 | ++newLineCount; 26 | for (auto letter : userInput) 27 | { 28 | ++totalCount; 29 | switch (letter) 30 | { 31 | case 'a': 32 | case 'A': 33 | ++aCount; 34 | break; 35 | case 'e': 36 | case 'E': 37 | ++eCount; 38 | break; 39 | case 'i': 40 | case 'I': 41 | ++iCount; 42 | break; 43 | case 'o': 44 | case 'O': 45 | ++oCount; 46 | break; 47 | case 'u': 48 | case 'U': 49 | ++uCount; 50 | break; 51 | case ' ': 52 | ++spaceCount; 53 | break; 54 | case '\t': 55 | ++tabCount; 56 | break; 57 | } 58 | } 59 | } 60 | cout << endl << "Processed " << totalCount << " characters." << endl; 61 | 62 | cout << "Number of vowel a: \t" << aCount << endl 63 | << "Number of vowel e: \t" << eCount << endl 64 | << "Number of vowel i: \t" << iCount << endl 65 | << "Number of vowel o: \t" << oCount << endl 66 | << "Number of vowel u: \t" << uCount << endl 67 | << "Number of spaces: \t" << spaceCount << endl 68 | << "Number of tabs: \t" << tabCount << endl 69 | << "Number of new lines: \t" << newLineCount << endl; 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /include/Sales_data_v4.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SALES_DATA_V4_HPP 2 | #define SALES_DATA_V4_HPP 3 | 4 | #include 5 | #include 6 | 7 | struct Sales_data 8 | { 9 | std::string bookNo; 10 | unsigned units_sold = 0; 11 | double revenue = 0.0; 12 | 13 | Sales_data() = default; 14 | 15 | Sales_data(const std::string& book_isbn) : bookNo(book_isbn) {} 16 | 17 | Sales_data(const std::string& book_isbn, unsigned units, double price) 18 | : bookNo(book_isbn) 19 | , units_sold(units) 20 | , revenue(units * price) 21 | { } 22 | 23 | Sales_data(std::istream& input); 24 | 25 | std::string isbn() const; 26 | Sales_data& combine(const Sales_data& transaction); 27 | 28 | }; // Sales_data class 29 | 30 | Sales_data add(const Sales_data& first_transaction, 31 | const Sales_data& second_transaction); 32 | std::istream& read(std::istream& input, Sales_data& transaction); 33 | std::ostream& print(std::ostream& output, const Sales_data& transaction); 34 | 35 | Sales_data::Sales_data(std::istream& input) 36 | { 37 | read(input, *this); 38 | } 39 | 40 | std::string Sales_data::isbn() const 41 | { 42 | return this->bookNo; 43 | } 44 | 45 | Sales_data& Sales_data::combine(const Sales_data& transaction) 46 | { 47 | if (this->isbn() == transaction.isbn()) 48 | { 49 | this->units_sold += transaction.units_sold; 50 | this->revenue += transaction.revenue; 51 | } 52 | return *this; 53 | } 54 | 55 | Sales_data add(const Sales_data& first_transaction, const Sales_data& second_transaction) 56 | { 57 | Sales_data sum = first_transaction; 58 | sum.combine(second_transaction); 59 | return sum; 60 | } 61 | 62 | std::istream& read(std::istream& input, Sales_data& transaction) 63 | { 64 | double price = 0.0; 65 | input >> transaction.bookNo >> transaction.units_sold >> price; 66 | transaction.revenue = transaction.units_sold * price; 67 | return input; 68 | } 69 | 70 | std::ostream& print(std::ostream& output, const Sales_data& transaction) 71 | { 72 | output << transaction.isbn() << " " 73 | << transaction.units_sold << " " 74 | << transaction.revenue; 75 | return output; 76 | } 77 | 78 | #endif // SALES_DATA_V4_HPP 79 | -------------------------------------------------------------------------------- /include/Sales_data_v5.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SALES_DATA_V5_HPP 2 | #define SALES_DATA_V5_HPP 3 | 4 | #include 5 | #include 6 | 7 | // Forward declarations 8 | struct Sales_data; 9 | Sales_data add(const Sales_data& first_transaction, 10 | const Sales_data& second_transaction); 11 | std::istream& read(std::istream& input, Sales_data& transaction); 12 | std::ostream& print(std::ostream& output, const Sales_data& transaction); 13 | 14 | struct Sales_data 15 | { 16 | std::string bookNo; 17 | unsigned units_sold = 0; 18 | double revenue = 0.0; 19 | 20 | Sales_data() = default; 21 | 22 | Sales_data(const std::string& book_isbn) : bookNo(book_isbn) {} 23 | 24 | Sales_data(const std::string& book_isbn, unsigned units, double price) 25 | : bookNo(book_isbn) 26 | , units_sold(units) 27 | , revenue(units * price) 28 | { } 29 | 30 | Sales_data(std::istream& input) 31 | { 32 | read(input, *this); 33 | } 34 | 35 | std::string isbn() const; 36 | Sales_data& combine(const Sales_data& transaction); 37 | 38 | }; // Sales_data class 39 | 40 | std::string Sales_data::isbn() const 41 | { 42 | return this->bookNo; 43 | } 44 | 45 | Sales_data& Sales_data::combine(const Sales_data& transaction) 46 | { 47 | if (this->isbn() == transaction.isbn()) 48 | { 49 | this->units_sold += transaction.units_sold; 50 | this->revenue += transaction.revenue; 51 | } 52 | return *this; 53 | } 54 | 55 | Sales_data add(const Sales_data& first_transaction, const Sales_data& second_transaction) 56 | { 57 | Sales_data sum = first_transaction; 58 | sum.combine(second_transaction); 59 | return sum; 60 | } 61 | 62 | std::istream& read(std::istream& input, Sales_data& transaction) 63 | { 64 | double price = 0.0; 65 | input >> transaction.bookNo >> transaction.units_sold >> price; 66 | transaction.revenue = transaction.units_sold * price; 67 | return input; 68 | } 69 | 70 | std::ostream& print(std::ostream& output, const Sales_data& transaction) 71 | { 72 | output << transaction.isbn() << " " 73 | << transaction.units_sold << " " 74 | << transaction.revenue; 75 | return output; 76 | } 77 | 78 | #endif // SALES_DATA_V5_HPP 79 | -------------------------------------------------------------------------------- /Chapter_02/exercise_42c.cpp: -------------------------------------------------------------------------------- 1 | // Write your own version of the Sales_data.h header and use it to rewrite 2 | // the exercise from § 2.6.2 (p. 76). 3 | 4 | // Exercise 1.22 rewritten using Sales_data header. 5 | 6 | #include 7 | #include 8 | #include "../include/Sales_data.hpp" 9 | 10 | int main() 11 | { 12 | Sales_data totalSales; 13 | 14 | // Read in the first transaction. All subsequent matches for this 15 | // transactions ISBN will be used in the total, the rest will be ignored. 16 | if (std::cin >> totalSales.bookNo 17 | >> totalSales.units_sold 18 | >> totalSales.price) 19 | { 20 | totalSales.revenue = totalSales.price * totalSales.units_sold; 21 | 22 | Sales_data currentTransaction; 23 | // If there are more transactions, read and print them 24 | while (std::cin >> currentTransaction.bookNo 25 | >> currentTransaction.units_sold 26 | >> currentTransaction.price) 27 | { 28 | // If ISBNs match continue processing 29 | if (totalSales.bookNo == currentTransaction.bookNo) 30 | { 31 | currentTransaction.revenue = currentTransaction.price * 32 | currentTransaction.units_sold; 33 | 34 | totalSales.units_sold += currentTransaction.units_sold; 35 | totalSales.revenue += currentTransaction.revenue; 36 | } 37 | } 38 | std::cout << "ISBN: " << totalSales.bookNo << std::endl 39 | << "Units sold: " << totalSales.units_sold << std::endl 40 | << "Total revenue: " << totalSales.revenue << std::endl; 41 | 42 | if (totalSales.units_sold) 43 | { 44 | std::cout << "Average Price (each): " 45 | << totalSales.revenue / totalSales.units_sold 46 | << std::endl; 47 | } 48 | 49 | return 0; 50 | } 51 | else 52 | { 53 | std::cerr << "No data or incomplete transaction" << std::endl 54 | << "Supply data of the format: ISBN units_sold price_each." 55 | << std::endl; 56 | 57 | return -1; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Chapter_02/exercise_41a.cpp: -------------------------------------------------------------------------------- 1 | // Use your Sales_data class to rewrite the exercises in § 1.5.1 2 | // (p. 22), § 1.52 (p.24), and § 1.6 (p.25). For now, you should 3 | // define your Sales_data class in the same file as your main function. 4 | 5 | // Exercise 1.20 rewritten using Sales_data class. 6 | 7 | #include 8 | #include 9 | 10 | // My version of the Sales_data class 11 | // Included 'price' member since the incoming data contains it. 12 | struct Sales_data { 13 | std::string bookNo; 14 | unsigned units_sold = 0; 15 | double price = 0.0; 16 | double revenue = 0.0; 17 | }; 18 | 19 | int main() 20 | { 21 | Sales_data transaction; 22 | 23 | // Read in the first transaction if there is one 24 | if (std::cin >> transaction.bookNo 25 | >> transaction.units_sold 26 | >> transaction.price) 27 | { 28 | transaction.revenue = transaction.price * transaction.units_sold; 29 | 30 | std::cout << "ISBN: " << transaction.bookNo << std::endl 31 | << "Units sold: " << transaction.units_sold << std::endl 32 | << "Price (each): " << transaction.price << std::endl 33 | << "Total revenue: " << transaction.revenue << std::endl 34 | << std::endl; 35 | 36 | // If there are more transactions, read and print them 37 | while (std::cin >> transaction.bookNo 38 | >> transaction.units_sold 39 | >> transaction.price) 40 | { 41 | transaction.revenue = transaction.price * transaction.units_sold; 42 | 43 | std::cout << "ISBN: " << transaction.bookNo << std::endl 44 | << "Units sold: " << transaction.units_sold << std::endl 45 | << "Price (each): " << transaction.price << std::endl 46 | << "Total revenue: " << transaction.revenue << std::endl 47 | << std::endl; 48 | } 49 | } 50 | else 51 | { 52 | std::cerr << "No data or incomplete transaction" << std::endl 53 | << "Supply data of the format: ISBN units_sold price_each." 54 | << std::endl; 55 | 56 | return -1; 57 | } 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /Chapter_02/exercise_42b.cpp: -------------------------------------------------------------------------------- 1 | // Write your own version of the Sales_data.h header and use it to rewrite 2 | // the exercise from § 2.6.2 (p. 76). 3 | 4 | // Exercise 1.21 rewritten using Sales_data header. 5 | 6 | #include 7 | #include 8 | #include "../include/Sales_data.hpp" 9 | 10 | int main() 11 | { 12 | Sales_data firstTransaction; 13 | Sales_data secondTransaction; 14 | 15 | // Read in two complete transactions 16 | if (std::cin >> firstTransaction.bookNo 17 | >> firstTransaction.units_sold 18 | >> firstTransaction.price && 19 | std::cin >> secondTransaction.bookNo 20 | >> secondTransaction.units_sold 21 | >> secondTransaction.price) 22 | { 23 | // If ISBNs match continue processing 24 | if (firstTransaction.bookNo == secondTransaction.bookNo) 25 | { 26 | firstTransaction.revenue = firstTransaction.price * 27 | firstTransaction.units_sold; 28 | secondTransaction.revenue = secondTransaction.price * 29 | secondTransaction.units_sold; 30 | 31 | auto totalSold = firstTransaction.units_sold + 32 | secondTransaction.units_sold; 33 | auto totalRevenue = firstTransaction.revenue + 34 | secondTransaction.revenue; 35 | 36 | std::cout << "ISBN: " << firstTransaction.bookNo << std::endl 37 | << "Units sold: " << totalSold << std::endl 38 | << "Total revenue: " << totalRevenue << std::endl; 39 | if (totalSold) 40 | { 41 | std::cout << "Average Price (each): " 42 | << totalRevenue / totalSold << std::endl; 43 | } 44 | 45 | return 0; 46 | } 47 | else 48 | { 49 | std::cerr << "Data must refer to the same ISBN." << std::endl; 50 | 51 | return -1; 52 | } 53 | } 54 | else 55 | { 56 | std::cerr << "No data or incomplete transaction" << std::endl 57 | << "Supply data of the format: ISBN units_sold price_each." 58 | << std::endl; 59 | 60 | return -1; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /include/Sales_data_v6.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SALES_DATA_V6_HPP 2 | #define SALES_DATA_V6_HPP 3 | 4 | #include 5 | #include 6 | 7 | // Forward declarations 8 | struct Sales_data; 9 | Sales_data add(const Sales_data& first_transaction, 10 | const Sales_data& second_transaction); 11 | std::istream& read(std::istream& input, Sales_data& transaction); 12 | std::ostream& print(std::ostream& output, const Sales_data& transaction); 13 | 14 | struct Sales_data 15 | { 16 | std::string bookNo; 17 | unsigned units_sold = 0; 18 | double revenue = 0.0; 19 | 20 | Sales_data() 21 | : bookNo("") 22 | , units_sold(0) 23 | , revenue(0.0) 24 | { } 25 | 26 | Sales_data(const std::string& book_isbn) : bookNo(book_isbn) {} 27 | 28 | Sales_data(const std::string& book_isbn, unsigned units, double price) 29 | : bookNo(book_isbn) 30 | , units_sold(units) 31 | , revenue(units * price) 32 | { } 33 | 34 | Sales_data(std::istream& input) 35 | { 36 | read(input, *this); 37 | } 38 | 39 | std::string isbn() const; 40 | Sales_data& combine(const Sales_data& transaction); 41 | 42 | }; // Sales_data class 43 | 44 | std::string Sales_data::isbn() const 45 | { 46 | return this->bookNo; 47 | } 48 | 49 | Sales_data& Sales_data::combine(const Sales_data& transaction) 50 | { 51 | if (this->isbn() == transaction.isbn()) 52 | { 53 | this->units_sold += transaction.units_sold; 54 | this->revenue += transaction.revenue; 55 | } 56 | return *this; 57 | } 58 | 59 | Sales_data add(const Sales_data& first_transaction, const Sales_data& second_transaction) 60 | { 61 | Sales_data sum = first_transaction; 62 | sum.combine(second_transaction); 63 | return sum; 64 | } 65 | 66 | std::istream& read(std::istream& input, Sales_data& transaction) 67 | { 68 | double price = 0.0; 69 | input >> transaction.bookNo >> transaction.units_sold >> price; 70 | transaction.revenue = transaction.units_sold * price; 71 | return input; 72 | } 73 | 74 | std::ostream& print(std::ostream& output, const Sales_data& transaction) 75 | { 76 | output << transaction.isbn() << " " 77 | << transaction.units_sold << " " 78 | << transaction.revenue; 79 | return output; 80 | } 81 | 82 | #endif // SALES_DATA_V6_HPP 83 | -------------------------------------------------------------------------------- /include/Sales_data_v7.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SALES_DATA_V7_HPP 2 | #define SALES_DATA_V7_HPP 3 | 4 | #include 5 | #include 6 | 7 | struct Sales_data 8 | { 9 | friend Sales_data add(const Sales_data& first_transaction, 10 | const Sales_data& second_transaction); 11 | friend std::istream& read(std::istream& input, Sales_data& transaction); 12 | friend std::ostream& print(std::ostream& output, const Sales_data& transaction); 13 | 14 | public: 15 | Sales_data() 16 | : bookNo("") 17 | , units_sold(0) 18 | , revenue(0.0) 19 | { } 20 | 21 | Sales_data(const std::string& book_isbn) : bookNo(book_isbn) {} 22 | 23 | Sales_data(const std::string& book_isbn, unsigned units, double price) 24 | : bookNo(book_isbn) 25 | , units_sold(units) 26 | , revenue(units * price) 27 | { } 28 | 29 | Sales_data(std::istream& input) 30 | { 31 | read(input, *this); 32 | } 33 | 34 | std::string isbn() const; 35 | Sales_data& combine(const Sales_data& transaction); 36 | 37 | private: 38 | std::string bookNo; 39 | unsigned units_sold = 0; 40 | double revenue = 0.0; 41 | 42 | }; // Sales_data class 43 | 44 | std::string Sales_data::isbn() const 45 | { 46 | return this->bookNo; 47 | } 48 | 49 | Sales_data& Sales_data::combine(const Sales_data& transaction) 50 | { 51 | if (this->isbn() == transaction.isbn()) 52 | { 53 | this->units_sold += transaction.units_sold; 54 | this->revenue += transaction.revenue; 55 | } 56 | return *this; 57 | } 58 | 59 | Sales_data add(const Sales_data& first_transaction, const Sales_data& second_transaction) 60 | { 61 | Sales_data sum = first_transaction; 62 | sum.combine(second_transaction); 63 | return sum; 64 | } 65 | 66 | std::istream& read(std::istream& input, Sales_data& transaction) 67 | { 68 | double price = 0.0; 69 | input >> transaction.bookNo >> transaction.units_sold >> price; 70 | transaction.revenue = transaction.units_sold * price; 71 | return input; 72 | } 73 | 74 | std::ostream& print(std::ostream& output, const Sales_data& transaction) 75 | { 76 | output << transaction.isbn() << " " 77 | << transaction.units_sold << " " 78 | << transaction.revenue; 79 | return output; 80 | } 81 | 82 | #endif // SALES_DATA_V7_HPP 83 | -------------------------------------------------------------------------------- /Chapter_06/exercise_03.cpp: -------------------------------------------------------------------------------- 1 | // Write and test your own version of `fact`. 2 | 3 | #include 4 | 5 | using std::cin; 6 | using std::cout; 7 | using std::endl; 8 | 9 | int fact(int n) 10 | { 11 | // if n = 0, nFactorial = 1 12 | // if n > 0, nFactorial = n * (n - 1) * (n - 2)... 13 | int nFactorial = 1; 14 | while (n > 1) 15 | { 16 | nFactorial *= n--; 17 | } 18 | return nFactorial; 19 | } 20 | 21 | void test() 22 | { 23 | // The max value of n! that an `int` can hold is 12! = 479,001,600 24 | cout << "============ TEST ============" << endl 25 | << "0! Should = 1\t\t" 26 | << (fact(0) == 1 ? "[PASS]" : "[FAIL]") << endl 27 | << "1! Should = 1\t\t" 28 | << (fact(1) == 1 ? "[PASS]" : "[FAIL]") << endl 29 | << "2! Should = 2\t\t" 30 | << (fact(2) == 2 ? "[PASS]" : "[FAIL]") << endl 31 | << "3! Should = 6\t\t" 32 | << (fact(3) == 6 ? "[PASS]" : "[FAIL]") << endl 33 | << "4! Should = 24\t\t" 34 | << (fact(4) == 24 ? "[PASS]" : "[FAIL]") << endl 35 | << "5! Should = 120\t" 36 | << (fact(5) == 120 ? "[PASS]" : "[FAIL]") << endl 37 | << "6! Should = 720\t" 38 | << (fact(6) == 720 ? "[PASS]" : "[FAIL]") << endl 39 | << "7! Should = 5040\t" 40 | << (fact(7) == 5040 ? "[PASS]" : "[FAIL]") << endl 41 | << "8! Should = 40320\t" 42 | << (fact(8) == 40320 ? "[PASS]" : "[FAIL]") << endl 43 | << "9! Should = 362880\t" 44 | << (fact(9) == 362880 ? "[PASS]" : "[FAIL]") << endl 45 | << "10! Should = 3628800\t" 46 | << (fact(10) == 3628800 ? "[PASS]" : "[FAIL]") << endl 47 | << "11! Should = 39916800\t" 48 | << (fact(11) == 39916800 ? "[PASS]" : "[FAIL]") << endl 49 | << "12! Should = 479001600\t" 50 | << (fact(12) == 479001600 ? "[PASS]" : "[FAIL]") << endl 51 | << "13! Should = 6227020800\t" 52 | << (fact(13) == 6227020800 ? "[PASS]" : "[FAIL]") << endl 53 | << "========== END TEST ==========" << endl; 54 | } 55 | 56 | int main() 57 | { 58 | test(); 59 | cout << "Factorial" << endl 60 | << "Enter an integer: "; 61 | int userInput; 62 | cin >> userInput; 63 | 64 | cout << userInput << "! = " << fact(userInput) << endl; 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /Chapter_03/exercise_01g.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the exercises from § 1.4.1 (p. 13) and § 2.6.2 (p. 76) 2 | // with appropriate using declarations. 3 | 4 | // Rewrite of a rewrite of exercise 1.23 5 | 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::cin; 11 | using std::endl; 12 | using std::string; 13 | using std::cerr; 14 | 15 | // My version of the Sales_data class 16 | // Included 'price' member since the incoming data contains it. 17 | struct Sales_data { 18 | string bookNo; 19 | unsigned units_sold = 0; 20 | double price = 0.0; 21 | double revenue = 0.0; 22 | }; 23 | 24 | int main() 25 | { 26 | Sales_data currentTransaction; 27 | 28 | if (cin >> currentTransaction.bookNo 29 | >> currentTransaction.units_sold 30 | >> currentTransaction.price) 31 | { 32 | currentTransaction.revenue = currentTransaction.price * 33 | currentTransaction.units_sold; 34 | int transactionsForIsbn = 1; 35 | Sales_data nextTransaction; 36 | 37 | // Read in the rest of the transactions 38 | while (cin >> nextTransaction.bookNo 39 | >> nextTransaction.units_sold 40 | >> nextTransaction.price) 41 | { 42 | nextTransaction.revenue = nextTransaction.price * 43 | nextTransaction.units_sold; 44 | 45 | if (currentTransaction.bookNo == nextTransaction.bookNo) 46 | { 47 | ++transactionsForIsbn; 48 | } 49 | else 50 | { 51 | cout << transactionsForIsbn 52 | << " Transaction(s) for ISBN '" 53 | << currentTransaction.bookNo << "'" << endl; 54 | transactionsForIsbn = 1; 55 | currentTransaction.bookNo = nextTransaction.bookNo; 56 | currentTransaction.units_sold = nextTransaction.units_sold; 57 | currentTransaction.price = nextTransaction.price; 58 | currentTransaction.revenue = nextTransaction.revenue; 59 | } 60 | } 61 | } 62 | else 63 | { 64 | cerr << "No data or incomplete transaction" << endl 65 | << "Supply data of the format: ISBN units_sold price_each." 66 | << endl; 67 | 68 | return -1; 69 | } 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /Chapter_03/exercise_01f.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the exercises from § 1.4.1 (p. 13) and § 2.6.2 (p. 76) 2 | // with appropriate using declarations. 3 | 4 | // Rewrite of a rewrite of exercise 1.22 5 | 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::cin; 11 | using std::endl; 12 | using std::string; 13 | using std::cerr; 14 | 15 | // My version of the Sales_data class 16 | // Included 'price' member since the incoming data contains it. 17 | struct Sales_data { 18 | string bookNo; 19 | unsigned units_sold = 0; 20 | double price = 0.0; 21 | double revenue = 0.0; 22 | }; 23 | 24 | int main() 25 | { 26 | Sales_data totalSales; 27 | 28 | // Read in the first transaction. All subsequent matches for this 29 | // transactions ISBN will be used in the total, the rest will be ignored. 30 | if (cin >> totalSales.bookNo 31 | >> totalSales.units_sold 32 | >> totalSales.price) 33 | { 34 | totalSales.revenue = totalSales.price * totalSales.units_sold; 35 | 36 | Sales_data currentTransaction; 37 | // If there are more transactions, read and print them 38 | while (cin >> currentTransaction.bookNo 39 | >> currentTransaction.units_sold 40 | >> currentTransaction.price) 41 | { 42 | // If ISBNs match continue processing 43 | if (totalSales.bookNo == currentTransaction.bookNo) 44 | { 45 | currentTransaction.revenue = currentTransaction.price * 46 | currentTransaction.units_sold; 47 | 48 | totalSales.units_sold += currentTransaction.units_sold; 49 | totalSales.revenue += currentTransaction.revenue; 50 | } 51 | } 52 | cout << "ISBN: " << totalSales.bookNo << endl 53 | << "Units sold: " << totalSales.units_sold << endl 54 | << "Total revenue: " << totalSales.revenue << endl; 55 | 56 | if (totalSales.units_sold) 57 | { 58 | cout << "Average Price (each): " 59 | << totalSales.revenue / totalSales.units_sold 60 | << endl; 61 | } 62 | 63 | return 0; 64 | } 65 | else 66 | { 67 | cerr << "No data or incomplete transaction" << endl 68 | << "Supply data of the format: ISBN units_sold price_each." 69 | << endl; 70 | 71 | return -1; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Chapter_02/exercise_41d.cpp: -------------------------------------------------------------------------------- 1 | // Use your Sales_data class to rewrite the exercises in § 1.5.1 2 | // (p. 22), § 1.52 (p.24), and § 1.6 (p.25). For now, you should 3 | // define your Sales_data class in the same file as your main function. 4 | 5 | // Exercise 1.23 rewritten using Sales_data class. 6 | 7 | #include 8 | #include 9 | 10 | // My version of the Sales_data class 11 | // Included 'price' member since the incoming data contains it. 12 | struct Sales_data { 13 | std::string bookNo; 14 | unsigned units_sold = 0; 15 | double price = 0.0; 16 | double revenue = 0.0; 17 | }; 18 | 19 | int main() 20 | { 21 | Sales_data currentTransaction; 22 | 23 | if (std::cin >> currentTransaction.bookNo 24 | >> currentTransaction.units_sold 25 | >> currentTransaction.price) 26 | { 27 | currentTransaction.revenue = currentTransaction.price * 28 | currentTransaction.units_sold; 29 | int transactionsForIsbn = 1; 30 | Sales_data nextTransaction; 31 | 32 | // Read in the rest of the transactions 33 | while (std::cin >> nextTransaction.bookNo 34 | >> nextTransaction.units_sold 35 | >> nextTransaction.price) 36 | { 37 | nextTransaction.revenue = nextTransaction.price * 38 | nextTransaction.units_sold; 39 | 40 | if (currentTransaction.bookNo == nextTransaction.bookNo) 41 | { 42 | ++transactionsForIsbn; 43 | } 44 | else 45 | { 46 | std::cout << transactionsForIsbn 47 | << " Transaction(s) for ISBN '" 48 | << currentTransaction.bookNo << "'" << std::endl; 49 | transactionsForIsbn = 1; 50 | currentTransaction.bookNo = nextTransaction.bookNo; 51 | currentTransaction.units_sold = nextTransaction.units_sold; 52 | currentTransaction.price = nextTransaction.price; 53 | currentTransaction.revenue = nextTransaction.revenue; 54 | } 55 | } 56 | } 57 | else 58 | { 59 | std::cerr << "No data or incomplete transaction" << std::endl 60 | << "Supply data of the format: ISBN units_sold price_each." 61 | << std::endl; 62 | 63 | return -1; 64 | } 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /Chapter_03/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(exercise_01a exercise_01a.cpp) 2 | add_executable(exercise_01b exercise_01b.cpp) 3 | add_executable(exercise_01c exercise_01c.cpp) 4 | add_executable(exercise_01d exercise_01d.cpp) 5 | add_executable(exercise_01e exercise_01e.cpp) 6 | add_executable(exercise_01f exercise_01f.cpp) 7 | add_executable(exercise_01g exercise_01g.cpp) 8 | add_executable(exercise_01h exercise_01h.cpp) 9 | add_executable(exercise_02a exercise_02a.cpp) 10 | add_executable(exercise_02b exercise_02b.cpp) 11 | add_executable(exercise_04a exercise_04a.cpp) 12 | add_executable(exercise_04b exercise_04b.cpp) 13 | add_executable(exercise_05a exercise_05a.cpp) 14 | add_executable(exercise_05b exercise_05b.cpp) 15 | add_executable(exercise_06 exercise_06.cpp) 16 | add_executable(exercise_07 exercise_07.cpp) 17 | add_executable(exercise_08a exercise_08a.cpp) 18 | add_executable(exercise_08b exercise_08b.cpp) 19 | add_executable(exercise_10 exercise_10.cpp) 20 | add_executable(exercise_14 exercise_14.cpp) 21 | add_executable(exercise_15 exercise_15.cpp) 22 | add_executable(exercise_16 exercise_16.cpp) 23 | add_executable(exercise_17 exercise_17.cpp) 24 | add_executable(exercise_20a exercise_20a.cpp) 25 | add_executable(exercise_20b exercise_20b.cpp) 26 | add_executable(exercise_21 exercise_21.cpp) 27 | add_executable(exercise_22 exercise_22.cpp) 28 | add_executable(exercise_23 exercise_23.cpp) 29 | add_executable(exercise_24a exercise_24a.cpp) 30 | add_executable(exercise_24b exercise_24b.cpp) 31 | add_executable(exercise_25 exercise_25.cpp) 32 | add_executable(exercise_31 exercise_31.cpp) 33 | add_executable(exercise_32a exercise_32a.cpp) 34 | add_executable(exercise_32b exercise_32b.cpp) 35 | add_executable(exercise_35 exercise_35.cpp) 36 | add_executable(exercise_36a exercise_36a.cpp) 37 | add_executable(exercise_36b exercise_36b.cpp) 38 | add_executable(exercise_39a exercise_39a.cpp) 39 | add_executable(exercise_39b exercise_39b.cpp) 40 | add_executable(exercise_40 exercise_40.cpp) 41 | add_executable(exercise_41 exercise_41.cpp) 42 | add_executable(exercise_42 exercise_42.cpp) 43 | add_executable(exercise_43a exercise_43a.cpp) 44 | add_executable(exercise_43b exercise_43b.cpp) 45 | add_executable(exercise_43c exercise_43c.cpp) 46 | add_executable(exercise_44a exercise_44a.cpp) 47 | add_executable(exercise_44b exercise_44b.cpp) 48 | add_executable(exercise_45c exercise_45c.cpp) 49 | add_executable(exercise_45a exercise_45a.cpp) 50 | add_executable(exercise_45b exercise_45b.cpp) 51 | add_executable(exercise_44c exercise_44c.cpp) 52 | -------------------------------------------------------------------------------- /Chapter_03/exercise_01e.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the exercises from § 1.4.1 (p. 13) and § 2.6.2 (p. 76) 2 | // with appropriate using declarations. 3 | 4 | // Rewrite of a rewrite of exercise 1.21 5 | 6 | #include 7 | #include 8 | 9 | using std::cout; 10 | using std::cin; 11 | using std::endl; 12 | using std::string; 13 | using std::cerr; 14 | 15 | // My version of the Sales_data class 16 | // Included 'price' member since the incoming data contains it. 17 | struct Sales_data { 18 | string bookNo; 19 | unsigned units_sold = 0; 20 | double price = 0.0; 21 | double revenue = 0.0; 22 | }; 23 | 24 | int main() 25 | { 26 | Sales_data firstTransaction; 27 | Sales_data secondTransaction; 28 | 29 | // Read in two complete transactions 30 | if (cin >> firstTransaction.bookNo 31 | >> firstTransaction.units_sold 32 | >> firstTransaction.price && 33 | cin >> secondTransaction.bookNo 34 | >> secondTransaction.units_sold 35 | >> secondTransaction.price) 36 | { 37 | // If ISBNs match continue processing 38 | if (firstTransaction.bookNo == secondTransaction.bookNo) 39 | { 40 | firstTransaction.revenue = firstTransaction.price * 41 | firstTransaction.units_sold; 42 | secondTransaction.revenue = secondTransaction.price * 43 | secondTransaction.units_sold; 44 | 45 | auto totalSold = firstTransaction.units_sold + 46 | secondTransaction.units_sold; 47 | auto totalRevenue = firstTransaction.revenue + 48 | secondTransaction.revenue; 49 | 50 | cout << "ISBN: " << firstTransaction.bookNo << endl 51 | << "Units sold: " << totalSold << endl 52 | << "Total revenue: " << totalRevenue << endl; 53 | if (totalSold) 54 | { 55 | cout << "Average Price (each): " 56 | << totalRevenue / totalSold << endl; 57 | } 58 | 59 | return 0; 60 | } 61 | else 62 | { 63 | cerr << "Data must refer to the same ISBN." << endl; 64 | 65 | return -1; 66 | } 67 | } 68 | else 69 | { 70 | cerr << "No data or incomplete transaction" << endl 71 | << "Supply data of the format: ISBN units_sold price_each." 72 | << endl; 73 | 74 | return -1; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /include/Sales_data_v8.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SALES_DATA_V8_HPP 2 | #define SALES_DATA_V8_HPP 3 | 4 | #include 5 | #include 6 | 7 | struct Sales_data 8 | { 9 | friend Sales_data add(const Sales_data& first_transaction, 10 | const Sales_data& second_transaction); 11 | friend std::istream& read(std::istream& input, Sales_data& transaction); 12 | friend std::ostream& print(std::ostream& output, const Sales_data& transaction); 13 | 14 | public: 15 | Sales_data() 16 | : bookNo("") 17 | , units_sold(0) 18 | , revenue(0.0) 19 | { } 20 | 21 | Sales_data(const std::string& book_isbn) : bookNo(book_isbn) {} 22 | 23 | Sales_data(const std::string& book_isbn, unsigned units, double price) 24 | : bookNo(book_isbn) 25 | , units_sold(units) 26 | , revenue(units * price) 27 | { } 28 | 29 | Sales_data(std::istream& input) 30 | { 31 | read(input, *this); 32 | } 33 | 34 | std::string isbn() const; 35 | Sales_data& combine(const Sales_data& transaction); 36 | double avg_price() const; 37 | 38 | private: 39 | std::string bookNo; 40 | unsigned units_sold = 0; 41 | double revenue = 0.0; 42 | double average_price = 0.0; 43 | 44 | }; // Sales_data class 45 | 46 | std::string Sales_data::isbn() const 47 | { 48 | return this->bookNo; 49 | } 50 | 51 | Sales_data& Sales_data::combine(const Sales_data& transaction) 52 | { 53 | if (this->isbn() == transaction.isbn()) 54 | { 55 | this->units_sold += transaction.units_sold; 56 | this->revenue += transaction.revenue; 57 | } 58 | return *this; 59 | } 60 | 61 | inline 62 | double Sales_data::avg_price() const 63 | { 64 | return this->units_sold ? this->revenue / this->units_sold : 0; 65 | } 66 | 67 | Sales_data add(const Sales_data& first_transaction, const Sales_data& second_transaction) 68 | { 69 | Sales_data sum = first_transaction; 70 | sum.combine(second_transaction); 71 | return sum; 72 | } 73 | 74 | std::istream& read(std::istream& input, Sales_data& transaction) 75 | { 76 | double price = 0.0; 77 | input >> transaction.bookNo >> transaction.units_sold >> price; 78 | transaction.revenue = transaction.units_sold * price; 79 | return input; 80 | } 81 | 82 | std::ostream& print(std::ostream& output, const Sales_data& transaction) 83 | { 84 | output << transaction.isbn() << " " 85 | << transaction.units_sold << " " 86 | << transaction.revenue; 87 | return output; 88 | } 89 | 90 | #endif // SALES_DATA_V8_HPP 91 | -------------------------------------------------------------------------------- /Chapter_02/exercise_41c.cpp: -------------------------------------------------------------------------------- 1 | // Use your Sales_data class to rewrite the exercises in § 1.5.1 2 | // (p. 22), § 1.52 (p.24), and § 1.6 (p.25). For now, you should 3 | // define your Sales_data class in the same file as your main function. 4 | 5 | // Exercise 1.22 rewritten using Sales_data class. 6 | 7 | #include 8 | #include 9 | 10 | // My version of the Sales_data class 11 | // Included 'price' member since the incoming data contains it. 12 | struct Sales_data { 13 | std::string bookNo; 14 | unsigned units_sold = 0; 15 | double price = 0.0; 16 | double revenue = 0.0; 17 | }; 18 | 19 | int main() 20 | { 21 | Sales_data totalSales; 22 | 23 | // Read in the first transaction. All subsequent matches for this 24 | // transactions ISBN will be used in the total, the rest will be ignored. 25 | if (std::cin >> totalSales.bookNo 26 | >> totalSales.units_sold 27 | >> totalSales.price) 28 | { 29 | totalSales.revenue = totalSales.price * totalSales.units_sold; 30 | 31 | Sales_data currentTransaction; 32 | // If there are more transactions, read and print them 33 | while (std::cin >> currentTransaction.bookNo 34 | >> currentTransaction.units_sold 35 | >> currentTransaction.price) 36 | { 37 | // If ISBNs match continue processing 38 | if (totalSales.bookNo == currentTransaction.bookNo) 39 | { 40 | currentTransaction.revenue = currentTransaction.price * 41 | currentTransaction.units_sold; 42 | 43 | totalSales.units_sold += currentTransaction.units_sold; 44 | totalSales.revenue += currentTransaction.revenue; 45 | } 46 | } 47 | std::cout << "ISBN: " << totalSales.bookNo << std::endl 48 | << "Units sold: " << totalSales.units_sold << std::endl 49 | << "Total revenue: " << totalSales.revenue << std::endl; 50 | 51 | if (totalSales.units_sold) 52 | { 53 | std::cout << "Average Price (each): " 54 | << totalSales.revenue / totalSales.units_sold 55 | << std::endl; 56 | } 57 | 58 | return 0; 59 | } 60 | else 61 | { 62 | std::cerr << "No data or incomplete transaction" << std::endl 63 | << "Supply data of the format: ISBN units_sold price_each." 64 | << std::endl; 65 | 66 | return -1; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Chapter_02/exercise_41b.cpp: -------------------------------------------------------------------------------- 1 | // Use your Sales_data class to rewrite the exercises in § 1.5.1 2 | // (p. 22), § 1.52 (p.24), and § 1.6 (p.25). For now, you should 3 | // define your Sales_data class in the same file as your main function. 4 | 5 | // Exercise 1.21 rewritten using Sales_data class. 6 | 7 | #include 8 | #include 9 | 10 | // My version of the Sales_data class 11 | // Included 'price' member since the incoming data contains it. 12 | struct Sales_data { 13 | std::string bookNo; 14 | unsigned units_sold = 0; 15 | double price = 0.0; 16 | double revenue = 0.0; 17 | }; 18 | 19 | int main() 20 | { 21 | Sales_data firstTransaction; 22 | Sales_data secondTransaction; 23 | 24 | // Read in two complete transactions 25 | if (std::cin >> firstTransaction.bookNo 26 | >> firstTransaction.units_sold 27 | >> firstTransaction.price && 28 | std::cin >> secondTransaction.bookNo 29 | >> secondTransaction.units_sold 30 | >> secondTransaction.price) 31 | { 32 | // If ISBNs match continue processing 33 | if (firstTransaction.bookNo == secondTransaction.bookNo) 34 | { 35 | firstTransaction.revenue = firstTransaction.price * 36 | firstTransaction.units_sold; 37 | secondTransaction.revenue = secondTransaction.price * 38 | secondTransaction.units_sold; 39 | 40 | auto totalSold = firstTransaction.units_sold + 41 | secondTransaction.units_sold; 42 | auto totalRevenue = firstTransaction.revenue + 43 | secondTransaction.revenue; 44 | 45 | std::cout << "ISBN: " << firstTransaction.bookNo << std::endl 46 | << "Units sold: " << totalSold << std::endl 47 | << "Total revenue: " << totalRevenue << std::endl; 48 | if (totalSold) 49 | { 50 | std::cout << "Average Price (each): " 51 | << totalRevenue / totalSold << std::endl; 52 | } 53 | 54 | return 0; 55 | } 56 | else 57 | { 58 | std::cerr << "Data must refer to the same ISBN." << std::endl; 59 | 60 | return -1; 61 | } 62 | } 63 | else 64 | { 65 | std::cerr << "No data or incomplete transaction" << std::endl 66 | << "Supply data of the format: ISBN units_sold price_each." 67 | << std::endl; 68 | 69 | return -1; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /include/Screen_v5.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SCREEN_V5_HPP 2 | #define SCREEN_V5_HPP 3 | 4 | #include 5 | #include 6 | 7 | class Screen; 8 | 9 | class Window_mgr 10 | { 11 | public: 12 | using Screen_index = std::vector::size_type; 13 | Window_mgr() = default; 14 | 15 | inline void clear(Screen_index id); 16 | private: 17 | std::vector screens; 18 | }; // Window_mgr class 19 | 20 | class Screen 21 | { 22 | friend void Window_mgr::clear(Window_mgr::Screen_index id); 23 | public: 24 | typedef std::string::size_type position; 25 | Screen() = default; 26 | Screen(position height, position width) 27 | : m_height(height) 28 | , m_width(width) 29 | , m_contents(height * width, ' ') 30 | {} 31 | Screen(position height, position width, char value) 32 | : m_height(height) 33 | , m_width(width) 34 | , m_contents(height * width, value) 35 | {} 36 | 37 | char get() const 38 | { 39 | return m_contents[m_cursor]; 40 | } 41 | 42 | position len() const 43 | { 44 | return m_contents.length(); 45 | } 46 | 47 | char get(position height, position width) const; 48 | 49 | Screen move(position row, position column); 50 | 51 | Screen set(char value); 52 | Screen set(position row, position column, char value); 53 | 54 | Screen display(std::ostream& output) 55 | { 56 | do_display(output); 57 | return *this; 58 | } 59 | 60 | const Screen display(std::ostream& output) const 61 | { 62 | do_display(output); 63 | return *this; 64 | } 65 | 66 | private: 67 | void do_display(std::ostream& output) const 68 | { 69 | output << m_contents; 70 | }; 71 | position m_cursor = 0; 72 | position m_height = 0; 73 | position m_width = 0; 74 | std::string m_contents; 75 | }; // Screen class 76 | 77 | #endif // SCREEN_V5_HPP 78 | 79 | inline 80 | void Window_mgr::clear(Screen_index i) 81 | { 82 | Screen& window = screens[i]; 83 | window.m_contents = std::string(window.m_height * window.m_width, ' '); 84 | } 85 | 86 | inline 87 | Screen Screen::move(position row, position column) 88 | { 89 | m_cursor = (row * m_width) + column; 90 | return *this; 91 | } 92 | 93 | inline 94 | char Screen::get(position row, position column) const 95 | { 96 | return m_contents[(row * m_width) + column]; 97 | } 98 | 99 | inline 100 | Screen Screen::set(char value) 101 | { 102 | m_contents[m_cursor] = value; 103 | return *this; 104 | } 105 | 106 | inline 107 | Screen Screen::set(position row, position column, char value) 108 | { 109 | m_contents[row * m_width + column] = value; 110 | return *this; 111 | } 112 | -------------------------------------------------------------------------------- /include/Screen_v6.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SCREEN_V6_HPP 2 | #define SCREEN_V6_HPP 3 | 4 | #include 5 | #include 6 | 7 | class Screen; 8 | 9 | class Window_mgr 10 | { 11 | public: 12 | using Screen_index = std::vector::size_type; 13 | Window_mgr() = default; 14 | 15 | inline void clear(Screen_index id); 16 | private: 17 | std::vector screens; 18 | }; // Window_mgr class 19 | 20 | class Screen 21 | { 22 | friend void Window_mgr::clear(Screen_index id); 23 | public: 24 | typedef std::string::size_type position; 25 | Screen() = default; 26 | Screen(position height, position width) 27 | : m_height(height) 28 | , m_width(width) 29 | , m_contents(height * width, ' ') 30 | {} 31 | Screen(position height, position width, char value) 32 | : m_height(height) 33 | , m_width(width) 34 | , m_contents(height * width, value) 35 | {} 36 | 37 | char get() const 38 | { 39 | return m_contents[m_cursor]; 40 | } 41 | 42 | position len() const 43 | { 44 | return m_contents.length(); 45 | } 46 | 47 | char get(position height, position width) const; 48 | 49 | Screen move(position row, position column); 50 | 51 | Screen set(char value); 52 | Screen set(position row, position column, char value); 53 | 54 | Screen display(std::ostream& output) 55 | { 56 | do_display(output); 57 | return *this; 58 | } 59 | 60 | const Screen display(std::ostream& output) const 61 | { 62 | do_display(output); 63 | return *this; 64 | } 65 | 66 | position size() const 67 | { 68 | return m_height * m_width; 69 | } 70 | 71 | private: 72 | void do_display(std::ostream& output) const 73 | { 74 | output << m_contents; 75 | }; 76 | position m_cursor = 0; 77 | position m_height = 0; 78 | position m_width = 0; 79 | std::string m_contents; 80 | }; // Screen class 81 | 82 | #endif // SCREEN_V6_HPP 83 | 84 | inline 85 | void Window_mgr::clear(Screen_index i) 86 | { 87 | Screen& window = screens[i]; 88 | window.m_contents = std::string(window.m_height * window.m_width, ' '); 89 | } 90 | 91 | inline 92 | Screen Screen::move(position row, position column) 93 | { 94 | m_cursor = (row * m_width) + column; 95 | return *this; 96 | } 97 | 98 | inline 99 | char Screen::get(position row, position column) const 100 | { 101 | return m_contents[(row * m_width) + column]; 102 | } 103 | 104 | inline 105 | Screen Screen::set(char value) 106 | { 107 | m_contents[m_cursor] = value; 108 | return *this; 109 | } 110 | 111 | inline 112 | Screen Screen::set(position row, position column, char value) 113 | { 114 | m_contents[row * m_width + column] = value; 115 | return *this; 116 | } 117 | -------------------------------------------------------------------------------- /Chapter_05/exercise_12.cpp: -------------------------------------------------------------------------------- 1 | // Modify our vowel-counting program so that it counts the number of 2 | // occurrences of the following two-character sequences: ff, fl, and fi. 3 | 4 | #include 5 | 6 | using std::cout; 7 | using std::cin; 8 | using std::endl; 9 | using std::string; 10 | 11 | int main() 12 | { 13 | int aCount = 0; 14 | int eCount = 0; 15 | int iCount = 0; 16 | int oCount = 0; 17 | int uCount = 0; 18 | int ffCount = 0; 19 | int flCount = 0; 20 | int fiCount = 0; 21 | int spaceCount = 0; 22 | int tabCount = 0; 23 | int newLineCount = 0; 24 | int totalCount = 0; 25 | char previousLetter = '\0'; 26 | string userInput; 27 | while (getline(cin, userInput)) 28 | { 29 | ++newLineCount; 30 | for (auto letter : userInput) 31 | { 32 | ++totalCount; 33 | switch (letter) 34 | { 35 | case 'a': 36 | case 'A': 37 | ++aCount; 38 | break; 39 | case 'e': 40 | case 'E': 41 | ++eCount; 42 | break; 43 | case 'i': 44 | if (previousLetter == 'f') 45 | { 46 | ++fiCount; 47 | } 48 | case 'I': 49 | ++iCount; 50 | break; 51 | case 'o': 52 | case 'O': 53 | ++oCount; 54 | break; 55 | case 'u': 56 | case 'U': 57 | ++uCount; 58 | break; 59 | case ' ': 60 | ++spaceCount; 61 | break; 62 | case '\t': 63 | ++tabCount; 64 | break; 65 | case 'f': 66 | if (previousLetter == 'f') 67 | { 68 | ++ffCount; 69 | } 70 | break; 71 | case 'l': 72 | if (previousLetter == 'f') 73 | { 74 | ++flCount; 75 | } 76 | break; 77 | } 78 | previousLetter = letter; 79 | } 80 | } 81 | cout << endl << "Processed " << totalCount << " characters." << endl; 82 | 83 | cout << "Number of vowel a: \t" << aCount << endl 84 | << "Number of vowel e: \t" << eCount << endl 85 | << "Number of vowel i: \t" << iCount << endl 86 | << "Number of vowel o: \t" << oCount << endl 87 | << "Number of vowel u: \t" << uCount << endl 88 | << "Occurrences of 'ff': \t" << ffCount << endl 89 | << "Occurrences of 'fl': \t" << flCount << endl 90 | << "Occurrences of 'fi': \t" << fiCount << endl 91 | << "Number of spaces: \t" << spaceCount << endl 92 | << "Number of tabs: \t" << tabCount << endl 93 | << "Number of new lines: \t" << newLineCount << endl; 94 | 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /Chapter_03/exercise_01h.cpp: -------------------------------------------------------------------------------- 1 | // Rewrite the exercises from § 1.4.1 (p. 13) and § 2.6.2 (p. 76) 2 | // with appropriate using declarations. 3 | 4 | // Rewrite of a rewrite of exercise 1.25 5 | 6 | #include 7 | #include 8 | #include "../include/Sales_data.hpp" 9 | 10 | using std::cout; 11 | using std::cin; 12 | using std::endl; 13 | using std::cerr; 14 | 15 | int main() 16 | { 17 | Sales_data totalTransactions; 18 | 19 | // Read in the first transaction 20 | if (cin >> totalTransactions.bookNo 21 | >> totalTransactions.units_sold 22 | >> totalTransactions.price) 23 | { 24 | totalTransactions.revenue = totalTransactions.price * 25 | totalTransactions.units_sold; 26 | 27 | Sales_data currentTransaction; 28 | 29 | // Read in the rest of the transactions 30 | while (cin >> currentTransaction.bookNo 31 | >> currentTransaction.units_sold 32 | >> currentTransaction.price) 33 | { 34 | currentTransaction.revenue = currentTransaction.price * 35 | currentTransaction.units_sold; 36 | 37 | if (totalTransactions.bookNo == currentTransaction.bookNo) 38 | { 39 | totalTransactions.units_sold += currentTransaction.units_sold; 40 | totalTransactions.price += currentTransaction.price; 41 | totalTransactions.revenue += currentTransaction.revenue; 42 | } 43 | else 44 | { 45 | cout << totalTransactions.bookNo << " " 46 | << totalTransactions.units_sold << " " 47 | << totalTransactions.revenue << " "; 48 | if (totalTransactions.units_sold) 49 | { 50 | cout << totalTransactions.revenue / 51 | totalTransactions.units_sold << endl; 52 | } 53 | totalTransactions.bookNo = currentTransaction.bookNo; 54 | totalTransactions.units_sold = currentTransaction.units_sold; 55 | totalTransactions.price = currentTransaction.price; 56 | totalTransactions.revenue = currentTransaction.revenue; 57 | } 58 | } 59 | cout << totalTransactions.bookNo << " " 60 | << totalTransactions.units_sold << " " 61 | << totalTransactions.revenue << " "; 62 | if (totalTransactions.units_sold) 63 | { 64 | cout << totalTransactions.revenue / 65 | totalTransactions.units_sold << endl; 66 | } 67 | } 68 | else 69 | { 70 | cerr << "No data or incomplete transaction" << endl 71 | << "Supply data of the format: ISBN units_sold price_each." 72 | << endl; 73 | 74 | return -1; 75 | } 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /Chapter_02/exercise_42f.cpp: -------------------------------------------------------------------------------- 1 | // Write your own version of the Sales_data.h header and use it to rewrite 2 | // the exercise from § 2.6.2 (p. 76). 3 | 4 | // Exercise 1.25 rewritten using Sales_data header. 5 | 6 | #include 7 | #include 8 | #include "../include/Sales_data.hpp" 9 | 10 | int main() 11 | { 12 | Sales_data totalTransactions; 13 | 14 | // Read in the first transaction 15 | if (std::cin >> totalTransactions.bookNo 16 | >> totalTransactions.units_sold 17 | >> totalTransactions.price) 18 | { 19 | totalTransactions.revenue = totalTransactions.price * 20 | totalTransactions.units_sold; 21 | 22 | Sales_data currentTransaction; 23 | 24 | // Read in the rest of the transactions 25 | while (std::cin >> currentTransaction.bookNo 26 | >> currentTransaction.units_sold 27 | >> currentTransaction.price) 28 | { 29 | currentTransaction.revenue = currentTransaction.price * 30 | currentTransaction.units_sold; 31 | 32 | if (totalTransactions.bookNo == currentTransaction.bookNo) 33 | { 34 | totalTransactions.units_sold += currentTransaction.units_sold; 35 | totalTransactions.price += currentTransaction.price; 36 | totalTransactions.revenue += currentTransaction.revenue; 37 | } 38 | else 39 | { 40 | std::cout << totalTransactions.bookNo << " " 41 | << totalTransactions.units_sold << " " 42 | << totalTransactions.revenue << " "; 43 | if (totalTransactions.units_sold) 44 | { 45 | std::cout << totalTransactions.revenue / 46 | totalTransactions.units_sold << std::endl; 47 | } 48 | totalTransactions.bookNo = currentTransaction.bookNo; 49 | totalTransactions.units_sold = currentTransaction.units_sold; 50 | totalTransactions.price = currentTransaction.price; 51 | totalTransactions.revenue = currentTransaction.revenue; 52 | } 53 | } 54 | std::cout << totalTransactions.bookNo << " " 55 | << totalTransactions.units_sold << " " 56 | << totalTransactions.revenue << " "; 57 | if (totalTransactions.units_sold) 58 | { 59 | std::cout << totalTransactions.revenue / 60 | totalTransactions.units_sold << std::endl; 61 | } 62 | } 63 | else 64 | { 65 | std::cerr << "No data or incomplete transaction" << std::endl 66 | << "Supply data of the format: ISBN units_sold price_each." 67 | << std::endl; 68 | 69 | return -1; 70 | } 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /Chapter_03/exercise_16.cpp: -------------------------------------------------------------------------------- 1 | // Write a program to print the size and contents of the vectors 2 | // from exercise 3.13. Check whether your answers to the exercise 3 | // were correct. If not, restudy § 3.3.1 (p. 97) until you understand 4 | // why you went wrong. 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using std::cout; 11 | using std::endl; 12 | using std::string; 13 | using std::vector; 14 | 15 | int main() 16 | { 17 | // Vectors from exercise 3.13 18 | vector v1; 19 | vector v2(10); 20 | vector v3(10, 42); 21 | vector v4{10}; 22 | vector v5{10, 42}; 23 | vector v6{10}; 24 | vector v7{10, "hi"}; 25 | 26 | cout << "v1 contains " << v1.size() << " element(s): "; 27 | if (v1.size()) 28 | { 29 | for (auto element : v1) 30 | { 31 | cout << element << " "; 32 | } 33 | cout << endl; 34 | } 35 | else 36 | { 37 | cout << "[empty vector]" << endl; 38 | } 39 | 40 | cout << "v2 contains " << v2.size() << " element(s): "; 41 | if (v2.size()) 42 | { 43 | for (auto element : v2) 44 | { 45 | cout << element << " "; 46 | } 47 | cout << endl; 48 | } 49 | else 50 | { 51 | cout << "[empty vector]" << endl; 52 | } 53 | 54 | cout << "v3 contains " << v3.size() << " element(s): "; 55 | if (v3.size()) 56 | { 57 | for (auto element : v3) 58 | { 59 | cout << element << " "; 60 | } 61 | cout << endl; 62 | } 63 | else 64 | { 65 | cout << "[empty vector]" << endl; 66 | } 67 | 68 | cout << "v4 contains " << v4.size() << " element(s): "; 69 | if (v4.size()) 70 | { 71 | for (auto element : v4) 72 | { 73 | cout << element << " "; 74 | } 75 | cout << endl; 76 | } 77 | else 78 | { 79 | cout << "[empty vector]" << endl; 80 | } 81 | 82 | cout << "v5 contains " << v5.size() << " element(s): "; 83 | if (v5.size()) 84 | { 85 | for (auto element : v5) 86 | { 87 | cout << element << " "; 88 | } 89 | cout << endl; 90 | } 91 | else 92 | { 93 | cout << "[empty vector]" << endl; 94 | } 95 | 96 | cout << "v6 contains " << v6.size() << " element(s): "; 97 | if (v6.size()) 98 | { 99 | for (auto element : v6) 100 | { 101 | cout << element << " "; 102 | } 103 | cout << endl; 104 | } 105 | else 106 | { 107 | cout << "[empty vector]" << endl; 108 | } 109 | 110 | cout << "v7 contains " << v7.size() << " element(s): "; 111 | if (v7.size()) 112 | { 113 | for (auto element : v7) 114 | { 115 | cout << element << " "; 116 | } 117 | cout << endl; 118 | } 119 | else 120 | { 121 | cout << "[empty vector]" << endl; 122 | } 123 | 124 | return 0; 125 | } 126 | -------------------------------------------------------------------------------- /Chapter_02/exercise_41f.cpp: -------------------------------------------------------------------------------- 1 | // Use your Sales_data class to rewrite the exercises in § 1.5.1 2 | // (p. 22), § 1.52 (p.24), and § 1.6 (p.25). For now, you should 3 | // define your Sales_data class in the same file as your main function. 4 | 5 | // Exercise 1.25 rewritten using Sales_data class. 6 | 7 | #include 8 | #include 9 | 10 | // My version of the Sales_data class 11 | // Included 'price' member since the incoming data contains it. 12 | struct Sales_data { 13 | std::string bookNo; 14 | unsigned units_sold = 0; 15 | double price = 0.0; 16 | double revenue = 0.0; 17 | }; 18 | 19 | int main() 20 | { 21 | Sales_data totalTransactions; 22 | 23 | // Read in the first transaction 24 | if (std::cin >> totalTransactions.bookNo 25 | >> totalTransactions.units_sold 26 | >> totalTransactions.price) 27 | { 28 | totalTransactions.revenue = totalTransactions.price * 29 | totalTransactions.units_sold; 30 | 31 | Sales_data currentTransaction; 32 | 33 | // Read in the rest of the transactions 34 | while (std::cin >> currentTransaction.bookNo 35 | >> currentTransaction.units_sold 36 | >> currentTransaction.price) 37 | { 38 | currentTransaction.revenue = currentTransaction.price * 39 | currentTransaction.units_sold; 40 | 41 | if (totalTransactions.bookNo == currentTransaction.bookNo) 42 | { 43 | totalTransactions.units_sold += currentTransaction.units_sold; 44 | totalTransactions.price += currentTransaction.price; 45 | totalTransactions.revenue += currentTransaction.revenue; 46 | } 47 | else 48 | { 49 | std::cout << totalTransactions.bookNo << " " 50 | << totalTransactions.units_sold << " " 51 | << totalTransactions.revenue << " "; 52 | if (totalTransactions.units_sold) 53 | { 54 | std::cout << totalTransactions.revenue / 55 | totalTransactions.units_sold << std::endl; 56 | } 57 | totalTransactions.bookNo = currentTransaction.bookNo; 58 | totalTransactions.units_sold = currentTransaction.units_sold; 59 | totalTransactions.price = currentTransaction.price; 60 | totalTransactions.revenue = currentTransaction.revenue; 61 | } 62 | } 63 | std::cout << totalTransactions.bookNo << " " 64 | << totalTransactions.units_sold << " " 65 | << totalTransactions.revenue << " "; 66 | if (totalTransactions.units_sold) 67 | { 68 | std::cout << totalTransactions.revenue / 69 | totalTransactions.units_sold << std::endl; 70 | } 71 | } 72 | else 73 | { 74 | std::cerr << "No data or incomplete transaction" << std::endl 75 | << "Supply data of the format: ISBN units_sold price_each." 76 | << std::endl; 77 | 78 | return -1; 79 | } 80 | 81 | return 0; 82 | } 83 | --------------------------------------------------------------------------------