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

Правка ru20, от Sanitator, 2019-02-22 14:25:56

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

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

    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 слишком большая) элементом контейнера.

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

Допустим, нужно посмотреть элементы в контейнере с 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: полностью переписан код

Теги tricks, debug, c++, dbg

История

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