C++ Tutorial
C++ Project: Contact Book
Store contacts in a map from name to number, then add, find, and list them in order.
What you will build
A contact book maps a name to a phone number. The type is std::map<string, string>: the key is the name, the value is the number. You add entries, look one up, and list every pair. A map keeps keys sorted, so the list is alphabetical by name, not insertion order.
Names and numbers are hardcoded. Compile with Try it in C++ at/cpp/try.
Insert with a key
Include <map> and <string>. Assignment throughbook[name] creates the key or replaces the number. That is the add-or-update operation.
Example
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<string, string> book;
book["Ada"] = "555-0101";
book["Lin"] = "555-0144";
cout << book["Ada"] << endl;
cout << book["Lin"] << endl;
return 0;
}Output is Ada’s number, then Lin’s. The keys are strings; the values are strings.
Find without inserting
Reading book[name] for a missing name inserts that name with an empty string. For a lookup, usecount or find. count(name) is 1 when the name exists and 0 when it does not. A map never stores duplicate keys.
Example
#include <iostream>
#include <map>
#include <string>
using namespace std;
void findContact(const map<string, string>& book, const string& name) {
if (book.count(name) == 0) {
cout << name << " not found" << endl;
return;
}
cout << name << ": " << book.at(name) << endl;
}
int main() {
map<string, string> book;
book["Ada"] = "555-0101";
findContact(book, "Ada");
findContact(book, "Omar");
return 0;
}at reads a key that you already know exists and throws if you were wrong. After thecount check, it is safe. Omar is not in the book, so you get the not-found line.
Try this in /cpp/try with Try it in C++. If you replacebook.at(name) with book[name] inside a const map, g++ will refuse to compile:operator[] is not const.
List in key order
A range-for on a map visits pair objects. item.first is the name.item.second is the number. Because this is std::map, the visit order is sorted keys.
Example
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<string, string> book;
book["Nia"] = "555-0199";
book["Ada"] = "555-0101";
book["Lin"] = "555-0144";
for (const auto& item : book) {
cout << item.first << " " << item.second << endl;
}
return 0;
}You inserted Nia first. The print order is still Ada, Lin, Nia.
Complete contact book
Helpers wrap add, find, and list. Add overwrites an old number for the same name, which is how you update a contact. main seeds three people, updates one number, looks up two names, then lists the book.
Example
#include <iostream>
#include <map>
#include <string>
using namespace std;
void addContact(map<string, string>& book, const string& name, const string& number) {
book[name] = number;
}
void findContact(const map<string, string>& book, const string& name) {
if (book.count(name) == 0) {
cout << "Find " << name << ": not found" << endl;
return;
}
cout << "Find " << name << ": " << book.at(name) << endl;
}
void listContacts(const map<string, string>& book) {
cout << "Contacts (" << book.size() << ")" << endl;
for (const auto& item : book) {
cout << item.first << " " << item.second << endl;
}
}
int main() {
map<string, string> book;
addContact(book, "Ada", "555-0101");
addContact(book, "Lin", "555-0144");
addContact(book, "Omar", "555-0170");
addContact(book, "Lin", "555-0202");
findContact(book, "Lin");
findContact(book, "Nia");
listContacts(book);
return 0;
}Lin’s number is the updated 555-0202. Nia is not found. The list has three rows in name order: Ada, Lin, Omar.
Common mistakes
- Looking up a missing name with
book[name]on a non-const map. That inserts a blank number and the next list shows a ghost contact. - Expecting insertion order.
std::mapsorts. If you need first-in order, a vector of structs is the other project style. - Using two parallel vectors for names and numbers. A map keeps one number per name without a search loop.
- Forgetting that keys are case-sensitive.
adais notAda.
Practice
- Refuse to add a contact whose name is an empty string, and print a reason.
- Print
not foundwhen listing an empty book, instead ofContacts (0)only. - Count how many numbers start with
555-by walking the map and checking each value.
Next project: turn numeric scores into letter grades and an average.