├── .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 " <
8 | #include
9 | #include
10 |
11 | using std::cout;
12 | using std::endl;
13 | using std::vector;
14 |
15 | void print_vector(vector::const_iterator beg,
16 | vector::const_iterator end)
17 | {
18 | if (beg != end) {
19 | #ifndef NDEBUG
20 | cout << "Vector size: " << (end - beg) << endl;
21 | #endif
22 | cout << *beg << endl;
23 | print_vector(++beg, end);
24 | }
25 | }
26 |
27 | int main()
28 | {
29 | vector 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