The sole objective of this project is to learn the practical use of various C++ features.
Besides serving as a handy reference for myself, the motive is to present these usages out in the wild. I hope these usages can be easily understood by new programmers.
git clone https://github.com/trunc8/fx-converter.git
cd fx-converter
# To run the project
make test
# To debug the project
make debug
- Command-line instructions are designed for Linux users
#include <iostream>; using namespace std;
applies to all snippets below
- Makefile
- Fetch data using web API
- Fetch data from file
- Parse json
- Operator Overloading
- Function Template
- Lambda Function
- Debug
For a quick guide on make
and Makefile
, please refer to my blog. The Makefile
in this project presents an easier example:
build: clean
g++ -Wall -o fx main.cpp utils.cpp -lcurl
clean:
rm -rf fx
test: build
./fx
For some intuition of the above code, running make test
on the terminal:
- first runs
clean
, i.e., the commandrm -rf fx
- then runs
build
, i.e., the commandg++ -Wall -o fx main.cpp utils.cpp -lcurl
- finally runs
./fx
So in a single terminal command, we removed the stale output file, compiled the source code, and ran the executable.
Ensure that curl
library is installed in your system. We ultimately want to include the curl.h
header file in our code. You can verify if the header file is available by checking if the directory /usr/include/x86_64-linux-gnu/curl
is present. While compiling, add -lcurl
at the end of the command.
Relevant lines from Makefile
:
build: clean
g++ -Wall -o fx main.cpp utils.cpp -lcurl
Relevant snippets from the project code:
#include <curl/curl.h>
size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
((string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
double getFxRate(string curr1, string curr2) {
...
string url_string = "https://free.currconv.com/api/v7/convert?q="
+curr1+"_"+curr2+"&compact=ultra&apiKey=b0591706cb6a10f406d5";
CURL *curl;
string readBuffer;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, url_string.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
...
}
We have currency_codes.txt
as a text file in the same directory.
Relevant snippets from the project code:
#include <fstream>
void fetchValidCurrency(set<string> &valid_curr) {
if (ifstream input{"currency_codes.txt"}) {
while (input) {
string line;
getline(input, line);
if (line.empty())
continue;
valid_curr.insert(line);
}
}
}
We shall use nlohmann's json library. Head to their GitHub releases. Scroll down to their latest assets. Download the json.hpp
file to the include
directory of your project.
Relevant snippets from the project code:
#include "json.hpp"
using json = nlohmann::json;
double getFxRate(string curr1, string curr2) {
double _fx_rate = 0;
... // string readBuffer contains json text in string format
// Using nlohmann json
json fx_json = json::parse(readBuffer);
// Pretty print in json format
// cout << setw(4) << fx_json << std::endl;
_fx_rate = fx_json.at(curr1+"_"+curr2);
return _fx_rate;
}
Relevant snippets from the project code:
ostream &operator<<(ostream &os, const set<string> &s) {
for (auto const &i: s) {
os << i << " ";
}
os << "\n";
return os;
}
Relevant snippets from the project code:
template<typename T>
void printSet(set<T> const &s) {
// for(auto i : s) makes a copy of each element of s
for (auto const &i: s) {
cout << i << " ";
}
cout << endl;
}
Relevant snippets from the project code:
int main(void) {
...
// Using lambda expression
auto validateCurrency = [valid_curr](string curr) -> bool {
return valid_curr.find(curr) != valid_curr.end();
};
if (!validateCurrency(curr1) || !validateCurrency(curr2)) {
cout << "Please use valid currency code. Exiting.\n";
}
else {
...
}
...
}
Ensure that gdb
is installed in your system. We need to pass an additional flag (-g
) while compiling in order to use gdb later.
Relevant lines from Makefile
:
debug: clean
g++ -Wall -g -o fx main.cpp utils.cpp -lcurl
gdb -tui fx
Useful gdb shortcuts:
- q: quit
- b: breakpoint (on line number)
- r: run (program)
- l: list (print source code till that point)
- p: print (variable)
- c: continue (until next breakpoint)
- n: next (line in function)
- s: step (next innermost instruction)
- fin: finish (continue until just after current function returns)
- ENTER: repeat previous command
- bt: backtrack (backtrace stack frames)
- Siddharth Saha - trunc8
Created with ❤️ by Siddharth