It's time for the next homework. We now know a lot about writing functions, putting them into header and source files and organizing all of those into libraries, so it's about time we put it to the test.
Today we will write a small library for string processing with an unassuming name "no_strings_attached"
😉
Speaking about "putting to the test", you will have to write tests for your library.
We'll also implement a couple of examples to show how this library works.
They all live in the examples folder and allow to:
- Split strings by running:
examples/split_strings
- Trim strings by running:
examples/trim_strings
That's about it. Please see below for a formal definition of the homework. And good luck!
The main task of this homework is to write a library that splits and trims strings. It is checked in two ways:
- Through tests using the
googletest
framework - Through binaries in the
examples
folder
Below we cover all the details that you might need for the implementation.
Please make sure you've done the previous homework and that you're comfortable with all lectures since that homework until this one. The Readme is a convenient way to check this.
The project has to be implemented in the homework_4
folder in your homework repository (that you can create from this template). Otherwise automatic checking won't work.
The project must follow the template described in the CMake and GoogleTest lectures.
Here is how the structure of the project folder will look like:
homework_4/
└── no_strings_attached/
├── CMakeLists.txt
├── external
│ ├── CMakeLists.txt
│ └── googletest/ # Googletest library as a submodule
├── examples
│ ├── CMakeLists.txt
│ ├── split_strings.cpp
│ └── trim_strings.cpp
├── no_strings_attached/
│ ├── CMakeLists.txt # Defines all libraries
│ ├── string_split.cpp
│ ├── string_split.h
│ ├── string_split_test.cpp
│ └── ... # Same for all other libraries
├── .clang-format
└── readme.md # Description of your project. Go nuts!
Here is a more formal definition about what the libraries must do and how they should be organized.
Just as we discussed in the videos, make sure that the namespaces follow the project structure. Thus, all functions in this project must live in the no_strings_attached
namespace.
There will be 2 libraries (more concretely, CMake targets), one per functionality:
string_split
string_trim
These libraries must all be defined in the no_strings_attached/CMakeLists.txt
so that the binaries in the examples
folder and the tests could be linked to those.
They also should have header files so that they can be included with:
#include <no_strings_attached/string_split.h>
#include <no_strings_attached/string_trim.h>
💡 Such small libraries are a bit excessive for the real world use, but we are learning how to write libraries here, so it'll do 😉
- Splitting strings library
string_split
should have the following functions:-
A function to split a given string into a vector of strings from the right given a delimiter:
std::vector<std::string> Split(const std::string& str, const std::string& delimiter);
💡 Hint: You might want to use the
find
method fromstd::string
when implementing this function.Examples:
Split("hello world", " ")
➡️std::vector{"hello", "world"}
Split("aaabaaba", "aa")
➡️std::vector{"", "ab", "ba"}
-
An overload of the above function that allows keeping only part of the output:
std::vector<std::string> Split(const std::string& str, const std::string& delimiter, int number_of_chunks_to_keep);
Examples:
Split("hello world", " ", 1)
➡️std::vector{"hello"}
Split("hello world", " ", 2)
➡️std::vector{"hello", "world"}
Split("aaabaaba", "aa", 2)
➡️std::vector{"", "ab"}
-
- Trimming strings library
string_trim
should have the following things:- An
enum class
calledSide
that defines these options:Side::kLeft
Side::kRight
Side::kBoth
💡 Think where you want to put this enumeration. Should it live in a separate header?
- A function that allows trimming strings from a given direction:
Examples:
std::string Trim(const std::string& str, char char_to_trim, Side side);
Trim(" hello ", ' ', Side::kLeft)
➡️std::string{"hello "}
Trim(" hello ", ' ', Side::kRight)
➡️std::string{" hello"}
Trim(" hello ", ' ', Side::kBoth)
➡️std::string{"hello"}
Trim("hello", 'h', Side::kLeft)
➡️std::string{"ello"}
- An overload of this function function that allows trimming spaces from both sides:
Examples:
std::string Trim(const std::string& str);
Trim(" hello ")
➡️std::string{"hello"}
- An
All of the libraries must have unit tests using the googletest
framework available as a submodule in the project's external
folder, just like it is presented in the Googletest lecture. All of the tests must live in the same folder as the file that contains the code that they test and must be registered through ctest
.
For validating the right functionality, the homework checking system will inject an additional folder validation_test
into your project and run the custom-designed tests on your code. This will show up as a separate line in the output from the homework checker in your PR and wiki.
To show off the functionality we will also have binaries that use this functionality. These should be reachable after building the project under these paths and behave as follows:
- The binary to split string:
build/examples/split_strings
- It should ask the user for a string and print this string split on the
" "
character with every word surrounded in'
characters - Example:
echo "hello world" | ./build/examples/split_strings Example program that splits strings. Please enter a string: Your split string: 'hello' 'world'
- It should ask the user for a string and print this string split on the
- The binary to trim strings:
build/examples/trim_strings
- It should ask the user for a string and trim the spaces around it. It should then print this string to the terminal surrounded in
'
characters - Example:
echo " hello world " | ./build/examples/trim_strings Example program that trims strings. Please enter a string: Your trimmed string: 'hello world'
- It should ask the user for a string and trim the spaces around it. It should then print this string to the terminal surrounded in
💡 In your binaries, you might want to use the
std::getline
function instead of usingstd::cin
as the latter splits input on the space character, while the former does not.
Congratulations! You've implemented your own library in relatively modern C++! On to the next challenge! Do share your thoughts on the whole process in the discussions page 🙏.