how to print many variables with there name and their corresponding value in c++?

有些话、适合烂在心里 提交于 2021-02-09 09:55:32

问题


#include <bits/stdc++.h>
using namespace std;

#define __deb(X...) (cout << "[" << #X << "]:" << X)
template <typename... type>
void debug(type &&... args)
{
    ((__deb(args)), ...);
}

int main()
{
    int a = 1, b = 3;
    debug(a,b);
    return 0;
}

I got output like [args]:1[args]:3 but I wanted output like [a]:1[b]:3


回答1:


One way could be to quote all the macro arguments using #__VA_ARGS__ and parse that string in the C++ function.

Example:

#include <iostream>
#include <sstream>
#include <string>
#include <utility>

template<typename T, typename... Args>
std::string debug_detail(const char* names, T&& var, Args&&... args) {
    std::stringstream builder;

    // find variable end
    const char* end = names;
    while(*end != ',' && *end != '\0') ++end;

    // display one variable
    (builder << ' ').write(names, end - names) << '=' << var;

    // continue parsing?
    if constexpr(sizeof...(Args) > 0) {
        // recursively call debug_detail() with the new beginning for names
        builder << debug_detail(end + 1, std::forward<Args>(args)...);
    }

    return builder.str();
}

template<typename... Args>
void debug_entry(const char* file, int line, const char* func,
                 const char* names, Args&&... args) {
    std::stringstream retval;

    // common debug info
    retval << file << '(' << line << ") " << func << ':';

    // add variable info
    retval << debug_detail(names, std::forward<Args>(args)...) << '\n';

    std::cout << retval.str();
}

// the actual debug macro
#define debug(...) \
    debug_entry(__FILE__,__LINE__,__func__,#__VA_ARGS__,__VA_ARGS__)

int main() {
    int foo = 1;
    const int bar = 2;
    const std::string& Hello = "world";
    debug(foo,bar,Hello);
}

Possible output:

./example.cpp(48) main: foo=1 bar=2 Hello=world

Demo




回答2:


Here's my humble attempt, which uses a macro FOO to create a pair of the variable name and its value, and passes the arguments to a variadic function:

#include <utility>
#include <iostream>

#define FOO(var) std::make_pair(std::string(#var), var)

template <typename T>
void __deb(std::pair<std::string, T> arg) { std::cout << "[" << arg.first << "]:" << arg.second; }

template <typename... type>
void debug(std::pair<std::string, type> &&... args)
{
    (__deb(args), ...);
}

int main()
{
    int a = 1, b = 3;
    debug(FOO(a), FOO(b));
}

Demo


Alternatively, to avoid having a macro call FOO for each variable in debug, you could define debug as a macro that accepts #__VA_ARGS__ (string of arguments) and __VA_ARGS__ (argument values). Then parse each variable name and value:

#include <iostream>
#include <sstream>
#include <stdio.h>

#define debug(...) debug_print(#__VA_ARGS__,__VA_ARGS__)

template <typename T>
void __deb(std::istringstream &ss, T arg)
{
    //Extract name from stream
    std::string name;
    std::getline(ss, name, ',');
    //trim leading space
    const auto pos(name.find_first_not_of(" "));
    name.erase(0, pos);
    std::cout << "[" << name << "]:" << arg;
}

template <typename... type>
void debug_print(const char* names, type&&...args)
{
    std::istringstream ss(names);
    (__deb(ss, args), ...);
}


int main()
{
    int a = 1, b = 3, c = 4;
    debug(a, b, c);
}

Demo




回答3:


The problem is that the MACRO is used in the context of void debug(type &&... args), which is not familiar with the names a and b.

A possible solution to your problem is to implement a bigger MACRO which gats several vars and calls a sub-MACRO which handles a single var (which you already implemented).

This way the initial MACRO call will happen in the context of the calling function which has the wanted vars



来源:https://stackoverflow.com/questions/64213475/how-to-print-many-variables-with-there-name-and-their-corresponding-value-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!