Debugging the traditional way
Virtually every competitive programmer sometimes needs to print the values from some container, or array, or just a variable during debugging. This is where appear those ugly nested loops which take several minutes to write:
vector<int> a[2][2] = {{{2,3}, {4}}, {{6,2}, {4,5}}};
for(int i = 0; i < size(a); ++i, cout << endl){
for(int j = 0; j < min(4, int(size(a[i]))); ++j, cout << endl){
for(int k = 0; k < min(3, int(size(a[i][j]))); ++k){
cout << a[i][j][k] << ' ';
}
}
}
OMG, and bound checking for simple output of an array of vectors? 2D, 3D, it doesn't matter anymore if we can't write it concisely.
Debugging with f_dbg()
I was fed up with traditional this and wrote a simple 4-liner for printing almost everything one might want. The output is in python style. It has some limitations, but generally I like it.
You can find it here. My code exploits C++17 features, so choose the appropriate compiler.
How formatted debug works
Let me call c-array, vector, deque, array just arr. Then, basically, f_dbg()
can output sub-arr. To print sub-arr, you pass coordinates of its start and the coordinates of its end, id est, of the cells with the smallest and the largest coordinates of sub-arr. If they are too large, f_dbg()
reduces them, so that they are inside the arr. By default the starting cell is the first cell of arr, last cell — the last cell of arr.
If type of element of arr is some other arr-type, f_dbg()
is recursively called with this element as argument until the simplest types are reached. You know them: int, char, double, and so on. They are then neatly printed, and that's all.
Other data structures like maps, sets don't have any indices, that's why they are printed from begin to end. In maps, f_dbg()
is called both from the key and the value.
Pairs are printed the same way — recursive f_dbg()
from the first element and from the second.
/*-----------------------------------------------*/
It is better to print the main types with macro function _()
. It uses the syntax of dbg()
function and just substitutes the bare variable with its name, colon, value, and comma. It's created only to not write cout << "a: " << a << ","
every time;
/*-----------------------------------------------*/
Hope this code saves your precious minutes during contests. Enjoy.
P.S. if you want to look at the extended version and suggest any improvements, you can find it here.
P.P.S. If you want to adapt this code to c++11 or 14, I don't mind if you clone this blog for (c++11/14 edition). Alternatively, you can suggest me your code to add to this post, so that all versions are together.