Reputation: 3347
When I was in college i did some C/C++, but in near future i was working in PHP, and now I wish to put more time in learning C/C++.
In PHP i was using print_r() or var_dump() in order to display datas from structures or arrays. Do I have such a default functionality in C, in order to see what do i have in a struct or array?
Upvotes: 34
Views: 31742
Reputation: 56
I usually use GDB printing.
for example this code:
#include <string.h>
struct _example_ {
int a;
int b;
char c[20];
};
int main(){
struct _example_ example;
example.a = 1;
example.b = 2;
strcpy(example.c,"example_c");
}
compile with gcc main.c -o executable -g
if you want to know the values for the struct example, you should execute the program with GDB, put a break on the line that you want and then print the variable, like below.
Breakpoint 1, main () at main.c:12
12 strcpy(example.c,"example_c");
(gdb) n
13 }
(gdb) print example
$1 = {a = 1, b = 2, c = "example_c\000\000\000\000\000\000\000`PUU"}
(gdb)
In this case i put breakpoint on line 12, and print the variable example, then i got all the variables and values on the struct example
Upvotes: 0
Reputation: 10493
C++ in itself doesn't provide something like var_dump, but with libraries like Boost.Fusion and the ADAPT_STRUCT and ADAPT_ADT facility it's easily doable.
Indeed as told in the other response, the C++ compiler doesn't generate the metadata needed to generate such an output. However it is possible to generate these metadata and use a bit of template metaprogramming to use them.
That way I've implemented here an adapted_struct_printer, which can print std::container, any classes or structures, boost::variant and boost::tuple.
Now you can easily do the following :
#include <iostream>
#include <pre/json/to_json.hpp>
struct customer {
std::string name;
size_t money_spent;
std::vector<std::string> interests;
};
BOOST_FUSION_ADAPT_STRUCT(customer,
name,
money_spent,
interests)
...
customer my_customer{
"Mr. Dupond",
1000,
{"sport articles", "food", "tools"}
};
std::cout << pre::json::to_json(my_customer) << std::endl;
You can inversely with this library also do from_json to populate structures from json.
A documentation is available here : http://daminetreg.github.io/lib-cpp-pre/html/namespacepre_1_1json.html#a4325d2cdd64a7e321303fd4428f298b9
The only requirement is that you call BOOST_FUSION_ADAPT_STRUCT/BOOST_FUSION_ADAPT_ADT on your classes (See http://www.boost.org/doc/libs/1_57_0/libs/fusion/doc/html/fusion/adapted.html)
So that this example :
#include <iostream>
#include <swissarmyknife/boost/fusion/adapted_struct_printer.hpp>
#include <boost/fusion/include/define_struct.hpp>
#include <boost/variant.hpp>
#include <boost/tuple/tuple.hpp>
namespace bla {
struct someclass {
int i = 12;
int j = 15;
};
using boost::fusion::detail::operator <<;
}
BOOST_FUSION_ADAPT_STRUCT(bla::someclass,
(int, i)
(int, j)
)
BOOST_FUSION_DEFINE_STRUCT((bla), innerbim,
(std::string, mystring)
)
BOOST_FUSION_DEFINE_STRUCT((bla), bimbim,
(int, boom)
(int, bam)
(bla::innerbim, my_inner_bim)
)
typedef boost::variant<int, double, bla::innerbim> myvariant_t;
typedef boost::tuple<std::string, int, bla::innerbim, myvariant_t> my_tuple_t;
BOOST_FUSION_DEFINE_STRUCT((bla), blabla,
(bla::bimbim, bim)
(int, i)
(int, j)
(std::vector<double>, list)
(std::list<bla::bimbim>, list_of_bimbim)
(my_tuple_t, mytuple)
(myvariant_t, myvariant)
)
int main(int argc, char** argv) {
using namespace swak;
bla::blabla instance{
{22, 12, bla::innerbim{"COOL"} },
23,
43,
{2.00, 39.07, 24.05},
{
{24, 9, bla::innerbim{"FEEL GOOD"} },
{26, 14, bla::innerbim{"SO BAD"} },
},
{"Hey that's not an int", 1, bla::innerbim{"hello"}, 12},
bla::innerbim("I'm in the variant")
};
std::cout << instance << std::endl;
bla::someclass otherinstance{};
std::cout << "Other instance : " << otherinstance << std::endl;
return 0;
}
Prints out the following :
{
bim :
{
boom : 22,
bam : 12,
my_inner_bim :
{
mystring : COOL,
}
}
i : 23,
j : 43,
list : [2, 39.07, 24.05],
list_of_bimbim : [
{
boom : 24,
bam : 9,
my_inner_bim :
{
mystring : FEEL GOOD,
}
}
,
{
boom : 26,
bam : 14,
my_inner_bim :
{
mystring : SO BAD,
}
}
],
mytuple :
{
0 (Ss) : Hey that's not an int,
1 (i) : 1,
2 (N3bla8innerbimE) :
{
mystring : hello,
}
3 (N5boost7variantIidN3bla8innerbimENS_6detail7variant5void_ES5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_EE) :
{
12}
}
myvariant :
{
{
mystring : I'm in the variant,
}
}
}
Other instance :
{
i : 12,
j : 15,
}
I'm improving the implementation to get it at some point as a possible new feature in boost fusion, but it's already usable as shown there :
Upvotes: 9
Reputation: 73
In microsoft article have some solution:
https://msdn.microsoft.com/pt-br/library/7fthz5xd.aspx
template <typename T> void print_elem(const T& t) {
cout << "(" << t << ") ";
}
template <typename T> void print_collection(const T& t) {
cout << " " << t.size() << " elements: ";
for (const auto& p : t) {
print_elem(p);
}
cout << endl;
}
and the call for this:
cout << "vector data: " << endl;
print_collection(v);
Upvotes: 1
Reputation: 5433
It is possible but it would take a lot of work if debug symbols were enabled and all optimisations were disabled. Also it would be slow and perhaps not very reliable[*1].
Anything that a debugger can do could be replicated by a dump() function that causes a breakpoint, and logged out information.
Some debuggers can be automated, so perhaps the dump function itself would be written in the debugger.
*1 e.g. debuggers sometimes crash when dealing with some breakpoints. e.g. the program would need to have a breakpoint and halt all threads before trying to dump data. e.g. programs that need to deal with realtime interrupts probably wouldn't work. e.g. the debugger needs to be reliable enough to deal with many many breakpoints and not introduce other issues.
Upvotes: 1
Reputation:
There is no such functionality in C++. You can of course write your own Dump() functions. The reason such a feature cannot be generally provided is that the C++ compilation process removes the object metadata needed to structure the dump output. You can of course display structure contents in a debugger, where such metadata is maintained in the debug information.
BTW, are you asking about C or C++? The two languages are quite different, both in features and approach, although neither has var_dump() or similar.
Upvotes: 21
Reputation: 75724
No, there isn't. Use a debugger like ddd, for example. Most IDEs have one integrated.
Upvotes: 0
Reputation: 111200
No, you have to roll your own using one from the cout
or C style printf
family of output functions for user defined data structures. Similarly, for arrays, (except C-style strings) you will have to loop over all the elements and print each one.
Upvotes: 0