Удобный и мощный 4-строчник для дебага (C++11,14,17 эдишн)

Revision ru22, by Sanitator, 2019-02-23 11:30:01

Традиционный дебаг

Наверное, каждый спортивный программист хотя бы раз выводил в консоль содержимое контейнера, массива или просто значение переменной во время дебага. В этот момент появляются такие вот уродливые конструкции:

    vector<int> a[4][6] = {{{2,3}, {4}}, {{6,2}, {4,5}}};

    for(int i = 1; i < size(a); ++i, cout << endl){
        for(int j = 0; j < size(a[i]); ++j, cout << endl){
            for(int k : a[i][j]){
                cout << k << ' ';
            }
        }
    }

О, господи, да еще и гарантированная проверка, что счетчик не выходит за пределы массива! 2D, 3D, какая разница, если это нельзя записать кратко?! Да еще эти endlы вместо пустых ячеек...

Дебаг с dbg()

Мне надоело бесконечно набивать эти циклы, поэтому я написал несколько строчек, которые могут напечатать значения практически чего угодно, хранящего встроенные типы. Вывод сделан в стиле питона. Конечно, у этого кода есть некоторые ограничения, но в целом он мне нравится. В большой степени он основан на этой посылке tourist.

Вы можете найти мой код здесь.

Компактная версия сгенерирована из развернутой на сайте http://removelinebreaks.net/

Как работает dbg()

Допустим, у нас есть вложенные друг в друга контейнеры(vector, string, bitset, set, map) или массивы, которые мы можем для простоты рассматривать как просто многомерный массив со специфическими измерениями. dbg() может аккуратно вывести название и границы подмассива такого массива, а потом и сам подмассив.

Например:

    string g[2][2] = {{"ghdgh", "5445w"}, {"fghd", "sd3535f"}};
    dbg(g,0,1,0,1,0,1);

// вывод:
[g,0,1,0,1,0,1]: 
[["gh","54"],
 ["fg","sd"]]

Чтобы она сделала это, вы передаете ей по [две закрытые границы] для каждого измерения, причем можно опустить несколько последних границ. Если они слишком большие, dbg() уменьшает их, чтобы они были внутри массива. По умолчанию начальная и конечная граница для каждого измерения устанавливаются на начало и конец каждого измерения.

ВНИМАНИЕ!

++Если вы передаете границы [l, r] в измерение, которое map или set, вывод начинается с l-ного по возрастанию ключей элемента и заканчивается r-ным или последним(если граница r слишком большая) элементом контейнера.

++dbg() работает с c-массивами, чьи размеры измерений константны и известны на этапе компиляции.

первый пример
второй пример

++Если вы устанавливаете неправильные границы, вместо содержимого контейнера печатается пустая строка. /*-----------------------------------------------*/

Допустим, нужно посмотреть элементы в контейнере с 1го по 2ой.

    map<vector<int>, vector<string>> a = {{{3,4},{"sauron"}}, {{1,2},{"gandalf", "the", "gray"}}, {{5},{"frodo","bilbo"}}};
    
    // традиционная версия
    auto l = begin(a), r = begin(a);
    advance(l,1), advance(r, min(int(a.size()), 4));
    for(; l != r; ++l){
        cout << "{"; for(auto &ff : (*l).first) cout << ff << ","; cout << "}";
        cout << "{"; for(auto &ff : (*l).second) cout << ff << ","; cout << "}\n\n";
    } cout << "\n";
    
// вывод: 
{3,4,}{sauron,}
{5,}{frodo,bilbo,}

    // dbg():
    dbg(a,1,2);

// вывод:
[a,1,2]: 
[([3, 4], ["sauron"]), ([5], ["frodo", "bilbo"])]

Допустим, нужно вывести несколько переменных

    int t = 5; char u = 'R';
    pair<pair<double, unsigned int>, pair<int, string>> v = {{234.34534, 42}, {133, "IOI"}};
    
    // традиционная версия:
    #define fi first
    #define se second
    cout << t << " | " << u << " | " << "{ { " << v.fi.fi << "," << v.fi.se << " }{ " << v.se.fi << "," << v.se.se << " }\n"; 
    
// вывод:
5 | R | { { 234.345,42 }{ 133,IOI }


    // dbg
    dbg(t), dbg(u), dbg(v);
   
// вывод
[t]: 5
[u]: R
[v]: ((234.345340,42),(133,"IOI"))
    

/*-----------------------------------------------*/

Надеюсь, этот код сохранит немного вашего бесценного времени на контестах.

UPD: добавлена функция dbgs(), пофиксены endlы

Tags tricks, debug, c++, dbg

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en47 English Sanitator 2019-04-24 07:31:49 76
ru35 Russian Sanitator 2019-04-24 07:28:00 58
ru34 Russian Sanitator 2019-04-24 07:18:39 82
en46 English Sanitator 2019-04-23 19:51:03 576
ru33 Russian Sanitator 2019-04-23 19:46:43 38
ru32 Russian Sanitator 2019-04-23 19:45:30 38
ru31 Russian Sanitator 2019-04-23 19:43:47 607 Мелкая правка: ' с тестами\n**UPD2**' -> ' с тестами<br>\n**UPD2**'
en45 English Sanitator 2019-03-26 07:30:53 100
ru30 Russian Sanitator 2019-03-26 07:29:17 143
ru29 Russian Sanitator 2019-03-25 20:54:41 80
en44 English Sanitator 2019-03-25 20:53:58 79
en43 English Sanitator 2019-03-25 20:51:05 28
ru28 Russian Sanitator 2019-03-25 20:50:48 28 Мелкая правка: '/permlink/pXG09igiUEuyljHW). Он в зн' -> '/permlink/LMm2u1XmJcp929A1). Он в зн'
ru27 Russian Sanitator 2019-03-25 14:07:10 108
en42 English Sanitator 2019-03-25 14:05:28 77
ru26 Russian Sanitator 2019-03-25 11:56:21 395 Мелкая правка: 'ler>\n\nСпсибо за [э' -> 'ler>\n\nСпасибо за [э'
en41 English Sanitator 2019-03-25 11:53:18 382 Tiny change: '">\n~~~~~ void dbgs(' -> '">\n~~~~~ \nvoid dbgs('
ru25 Russian Sanitator 2019-03-25 11:34:02 14
ru24 Russian Sanitator 2019-03-25 11:33:25 7824 Мелкая правка: ' границ.\n \n~~~~~\n ' -> ' границ.\n\nНапример:\n\n~~~~~\n '
en40 English Sanitator 2019-03-25 11:22:03 2 Tiny change: 'e? Meet three helper f' -> 'e? Meet these helper f'
en39 English Sanitator 2019-03-25 11:20:15 34 (published)
en38 English Sanitator 2019-03-25 10:31:59 556 Tiny change: '-----*/`\n\n[Here's ' -> '-----*/`\n<br>\n[Here's '
en37 English Sanitator 2019-03-25 09:39:55 1
en36 English Sanitator 2019-03-25 09:39:31 2667 Tiny change: '---\n**D**e**B**u**G**\n\nS' -> '---\n**D** e **B** u **G**\n\nS'
en35 English Sanitator 2019-03-25 08:35:39 998
en34 English Sanitator 2019-03-25 07:07:59 690 (saved to drafts)
en33 English Sanitator 2019-03-09 11:24:19 65
ru23 Russian Sanitator 2019-03-09 11:22:17 84
en32 English Sanitator 2019-02-23 11:30:12 2
ru22 Russian Sanitator 2019-02-23 11:30:01 78
en31 English Sanitator 2019-02-23 11:28:48 2 Tiny change: 'n**UPD**: dbgs() added, en' -> 'n**UPD**: `dbgs()` added, en'
en30 English Sanitator 2019-02-23 11:28:13 59
en29 English Sanitator 2019-02-23 09:33:05 72
ru21 Russian Sanitator 2019-02-22 21:08:03 613
en28 English Sanitator 2019-02-22 20:54:23 17 Tiny change: 'sions are known' -> 'sions are constant and are known'
en27 English Sanitator 2019-02-22 20:51:52 10 Tiny change: 'ays whose dimension' -> 'ays whose sizes of dimension' (published)
en26 English Sanitator 2019-02-22 20:48:04 486 (saved to drafts)
en25 English Sanitator 2019-02-22 15:26:18 4
ru20 Russian Sanitator 2019-02-22 14:25:56 0 (опубликовано)
en24 English Sanitator 2019-02-22 14:25:45 3422 Tiny change: 'Hope this code saves you' -> 'Hope this function saves you' (published)
ru19 Russian Sanitator 2019-02-22 13:19:21 468 Мелкая правка: 'рована из полной на сайт' -> 'рована из развернутой на сайт'
ru18 Russian Sanitator 2019-02-21 21:00:57 26 Мелкая правка: '/permlink/IZ7rE5yhOTON3Q8f).\n\nКомп' -> '/permlink/ZuU99yZRY9fB852G).\n\nКомп'
en23 English Sanitator 2019-02-21 21:00:22 417 (saved to drafts)
ru17 Russian Sanitator 2019-02-21 20:48:44 297
ru16 Russian Sanitator 2019-02-21 19:48:46 3666 (сохранено в черновиках)
en22 English Sanitator 2019-02-20 03:06:00 763
ru15 Russian Sanitator 2019-02-20 02:48:59 1026 (опубликовано)
ru14 Russian Sanitator 2019-02-19 15:29:34 159 (сохранено в черновиках)
en21 English Sanitator 2019-02-19 11:38:06 21
ru13 Russian Sanitator 2019-02-19 11:37:04 6 Мелкая правка: 'есконечно писать эти ци' -> 'есконечно набивать эти ци'
ru12 Russian Sanitator 2019-02-19 11:34:06 100
en20 English Sanitator 2019-02-19 11:30:00 27
ru11 Russian Sanitator 2019-02-19 11:29:45 1417 Мелкая правка: '\n\n\n\n\nDebugging with `n_dbg()`' -> '\n\n\n\n\nДебаг с `n_dbg()`'
en19 English Sanitator 2019-02-19 11:11:58 50 (published)
en18 English Sanitator 2019-02-19 10:56:50 1015 Tiny change: '~~~~\n\n\n`/*-' -> '~~~~\n\n\n\n`/*-' (saved to drafts)
ru10 Russian Sanitator 2019-02-18 11:03:17 3 Мелкая правка: ' я сделал четырехстрочни' -> ' я сделал трехстрочни'
ru9 Russian Sanitator 2019-02-18 10:58:49 2
ru8 Russian Sanitator 2019-02-18 10:58:21 1092 (опубликовано)
en17 English Sanitator 2019-02-18 10:40:54 63
en16 English Sanitator 2019-02-18 10:37:16 4
en15 English Sanitator 2019-02-18 10:36:09 6 Tiny change: 'compiler. 3-line ve' -> 'compiler. \nThe 3-line ve'
en14 English Sanitator 2019-02-18 10:34:08 2
en13 English Sanitator 2019-02-18 09:49:25 1303 Tiny change: '~~\n\n\n\nf_dbg() output\n\' -> '~~\n\n\n\n`f_dbg()` output\n\'
ru7 Russian Sanitator 2019-02-18 08:08:49 316 (сохранено в черновиках)
en12 English Sanitator 2019-02-17 19:19:24 89
ru6 Russian Sanitator 2019-02-17 19:18:38 144
en11 English Sanitator 2019-02-17 19:15:47 56
en10 English Sanitator 2019-02-17 18:07:17 4
en9 English Sanitator 2019-02-17 17:54:08 2 Tiny change: '\noutput: s: `Hello worl' -> '\noutput: `s: Hello worl'
en8 English Sanitator 2019-02-17 17:52:14 5 Tiny change: '\nDebugging ' -> 'Debugging ' (published)
en7 English Sanitator 2019-02-17 17:50:17 278 (saved to drafts)
ru5 Russian Sanitator 2019-02-17 17:32:03 1622
en6 English Sanitator 2019-02-17 16:55:03 3 Tiny change: 'n#### How my formatted' -> 'n#### How formatted'
en5 English Sanitator 2019-02-17 16:52:30 1 Tiny change: 're reached You know ' -> 're reached. You know '
en4 English Sanitator 2019-02-17 16:50:38 1982 Tiny change: 'ly. \n\n\n----------------------\nDebuggin' -> 'ly. \n\n\nDebuggin'
ru4 Russian Sanitator 2019-02-17 14:06:48 3 Мелкая правка: 'IhQ5iUeQ).\nP.P.S. Е' -> 'IhQ5iUeQ). \n\nP.P.S. Е'
en3 English Sanitator 2019-02-17 14:04:51 0 (published)
ru3 Russian Sanitator 2019-02-17 14:04:21 0 (опубликовано)
en2 English Sanitator 2019-02-17 14:03:49 0 (saved to drafts)
ru2 Russian Sanitator 2019-02-17 14:02:12 1722 (сохранено в черновиках)
en1 English Sanitator 2019-02-17 13:45:05 1502 Initial revision for English translation
ru1 Russian Sanitator 2019-02-17 12:22:11 1502 Первая редакция (опубликовано)