Hi Codeforces! I'm a Japanese graduate student, and I've been programming as a hobby since I was 11. I started CP last year, and since then, I've been working on a C++ debugging library that can print variables of almost any type, like vectors, maps, tuples, and more. In this blog, I want to share it with you. Link: https://github.com/philip82148/cpp-dump
Feature Summary
A Wide Variety of Supported Types Section
Example Code
Large Image
Auto Indent Section
Example Code
Large Image
Customizable Output Color Section
Example Code
Large Image
20+ Manipulators to Change the Display Style Section
Example Code
Large Image
- The string representation of variables is similar to JavaScript, Python, and C++ syntax. The output is readable without being overloaded with information. (You can add more details using manipulators if you want.)
- The filename, line number, and function name can be included in the output.
- By using macros, cpp-dump supports user-defined types as well. There is no need to write new functions for printing.
See the Features section of the README for details.
Simple Usage
Pass variables to the cpp_dump()
macro. For more detailed usage, please see README of the repo.
Full Example Code
#include <bits/stdc++.h>
#include "path/to/cpp-dump/cpp-dump.hpp"
using namespace std;
int main() {
vector<vector<int>> my_vector{{3, 5, 8, 9, 7}, {9, 3, 2, 3, 8}};
cpp_dump(my_vector);
}
Let's try it!
- Clone the repo(
git clone https://github.com/philip82148/cpp-dump
) or download it (zip) (tar.gz) from Releases. - Compile & run the code below to test the library
#include <bitset>
#include <complex>
#include <iostream>
#include <map>
#include <optional>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <variant>
#include <vector>
#include "path/to/cpp-dump/cpp-dump.hpp"
namespace cp = cpp_dump;
using namespace std;
int main() {
bool my_bool = true;
double my_double = 3.141592;
int my_int = 65;
char my_char = 'a', LF_char = '\n';
string my_string = "This is a string.";
int *int_ptr = &my_int;
void *void_ptr = &my_int;
vector<vector<int>> my_vector{{3, 5, 8, 9, 7}, {9, 3, 2, 3, 8}};
set<char> my_set{'A', 'p', 'p', 'l', 'e'};
map<int, int> my_map{{2, 6}, {4, 6}, {5, 3}};
multiset<char> my_multiset{'A', 'p', 'p', 'l', 'e'};
multimap<int, int> my_multimap{{2, 4}, {4, 6}, {5, 3}, {4, 7}};
pair<int, char> my_pair{8, 'a'};
tuple<int, double, string> my_tuple{7, 4.5, "This is a string."};
queue<int> my_queue;
priority_queue<int> my_priority_queue;
stack<int> my_stack;
for (auto v : {1, 2, 3, 4, 5}) my_queue.push(v), my_priority_queue.push(v), my_stack.push(v);
bitset<8> my_bitset(0x3a);
complex<double> my_complex{1.0, -1.0};
optional<int> my_optional{15};
variant<int, string> my_variant{"This is a string."};
vector<pair<int, string>> vector_of_pairs{{1, "apple"}, {3, "banana"}};
CPP_DUMP_SET_OPTION(max_line_width, 100);
CPP_DUMP_SET_OPTION(max_iteration_count, 10);
clog << "\n// Basic Type" << endl;
cpp_dump(my_bool, my_double, my_int), cpp_dump(my_string, my_char, LF_char);
cpp_dump(int_ptr, void_ptr, nullptr);
clog << "\n// Container" << endl;
cpp_dump(my_vector);
clog << "\n// Set/Map" << endl;
cpp_dump(my_set), cpp_dump(my_map);
clog << "\n// Multiset/Multimap" << endl;
cpp_dump(my_multiset), cpp_dump(my_multimap);
clog << "\n// Tuple" << endl;
cpp_dump(my_tuple), cpp_dump(my_pair);
clog << "\n// FIFO/LIFO" << endl;
cpp_dump(my_queue), cpp_dump(my_priority_queue), cpp_dump(my_stack);
clog << "\n// Other" << endl;
cpp_dump(my_bitset), cpp_dump(my_complex);
cpp_dump(my_optional, nullopt), cpp_dump(my_variant);
clog << "\n// Combination" << endl;
cpp_dump(vector_of_pairs);
vector<vector<int>> some_huge_vector(100, vector<int>(100));
vector<vector<unsigned int>> unsigned_int_vector(100, vector<unsigned int>(100));
for (int i = 0; i < 100; ++i) {
for (int j = 0; j < 100; ++j) {
some_huge_vector[i][j] = ((i + 1) * 7 % 19 - 9) * ((j + 1) * 3 % 19 - 9);
unsigned_int_vector[i][j] = abs(some_huge_vector[i][j]);
}
}
clog << "\n// Manipulator Test" << endl;
cpp_dump(some_huge_vector | cp::back() | cp::both_ends() | cp::dec(2));
cpp_dump(some_huge_vector | cp::dec(2) | cp::index());
}
There are other installation methods, too. Please see the Installation section of the README for details.
Recommended usage in competitive programming
cpp_dump(vars...)
is long, so let's shorten it to dump(vars...)
by macro. For details, see For Competitive Programming Use section of the README.
#ifndef ONLINE_JUDGE
#include "path/to/cpp-dump/cpp-dump.hpp"
#define dump(...) cpp_dump(__VA_ARGS__)
#else
#define dump(...)
#endif
News
v0.7.0 released on August 19 has lots of new features.
If you're using an older version, please update it! (For git users, run git pull
)
Conclusion
I hope this library helps!
Also, if you could upvote this blog and give a star to the repo, I would really appreciate it.
This looks interesting! I'll definitely try it out!
I used to debug code with the following snippet, which I learned in a competitive programming course. It allows you to print any type of variable and pass multiple arguments to the
debug()
function. It's been really helpful for debugging.what about arrays and vectors?
But can it print my profile picture?
Bro is the GOAT, wow
Bro you have to reveal how you did this godly thing
There are many websites that do that lol. Not a big deal
Is it possible to support custom class/structure? (just like
print/disp
in gdb do)Edit: I see this can be achieved by using some macros or operator, but it would be more convenient if a default result can be provided (maybe diffcult to implement in c++)
Yes..., it is difficult to provide default results for custom classes in C++.
Using the
CPP_DUMP_DEFINE_EXPORT_OBJECT_GENERIC
macro is the easiest way to support user types.C++ reflection black MAGIC XD
If you want to customize the string representation of a custom class more flexibly, you can do it as follows.
For reference, you can support AtCoder Library's modint by calling the function recursively like this.
How do I turn off the color output?
Pls see the end of the Customizable output color section.
Why does it display the message as an error in cp editor?
cpp_dump()
outputs to the standard error output (std::clog
) by default. So, for example, if you want to change the output destination to the standard output (std::cout
), you can do it as follows.thank you very much
Ur welcome
Here is a list of all the supported types: Supported types
Since
cpp_dump()
prints variables recursively, it can print any combination of nested containers from the list.Hi. I found your library really helpful.
Just wanted your help on this thing :
The dump function is working perfectly fine when the output is shown on terminal. But when I am using the CPH Judge VS Code extension, the output being displayed is something like this :
I know you might not be aware of the CPH extension, but any suggestion from your side would be of great help.
Thanks.
I use cp editor but have encountered the same problem.
1) Disable the display of colored text using this code:
2)
cpp_dump()
outputs to the standard error output(std::clog)
by default. So, for example, if you want to change the output destination to the standard output(std::cout)
, you can do it as follows.this is the full code I'm using
Yeah, the output is now being formatted perfectly.
Thanks a lot!
For reference, the garbled character is '\x1b' (a char with a hex value of 0x1b), which is called an escape sequence and controls color.
Running this in the terminal helps you understand this.
Somehow I couldn't use cpeditor in my environment, so I didn't test, but probablly cpeditor doesn't recognize escape sequences.
This is advanced knowledge, but a terminal is treated as a file in macOS or Linux.
You can get the path of a terminal by the
tty
command.Note:
echo "something" > filepath
writes to a file.So, you can write the output of
cpp_dump()
to the terminal while using cpeditor like this.By doing this, you can still get colored output while using cpeditor.
I did it now, and
cpp_dump()
doesn't output anything.Did you change
/dev/pts/7
to your own terminal's path?The file path is the result of the
tty
command.Yeah, I did it.
Does this command work? It should produce the output 'ABC' in the terminal.
Sorry, I just realized what you want to do. My knowledge of linux is not that strong. So I thought this command would output the data in the cp editor itself.
It's OK. :)
I use vim and this is best debugger i have ever seen for cp even better than mine
Thanks.
my debugger cant give colored output and the structured way.
This is really useful! Especially since it's a header-only library. I added it as a git submodule to my project.
Great work! Upvoted and starred.
If you want to configure the library outside of the main function, you can use the
CPP_DUMP_SET_OPTION_GLOBAL()
macro.And here is the list of all available options: Configuration options
I switched to Windows and now it doesn't work, maybe I need to download another code just I don't understand it
It's tested on Windows too. It requires C++17 or higher. Are you using the correct version? If you are, could you provide the error message?
command: g++ -std=c++17 main.cpp
In file included from main.cpp:2:0: C:\Users\Muhammad\Documents\debug\cpp-dump\cpp-dump.hpp:16:23: fatal error: string_view: No such file or directory
#include <string_view>
^
compilation terminated.
Could you tell me the result of this command?