Когда я учился в колледже, я сделал несколько C / C ++, но в ближайшем будущем я работал в PHP, и теперь я хочу больше времени уделять изучению C / C ++.
В PHP я использовал print_r () или var_dump (), чтобы отображать данные из структур или массивов. Есть ли у меня такая функция по умолчанию в C, чтобы узнать, что у меня есть в структуре или массиве?
В C ++ таких функций нет. Вы можете, конечно, написать свои собственные функции Dump (). Причина, по которой такая функция вообще не может быть предоставлена, заключается в том, что процесс компиляции C ++ удаляет метаданные объекта, необходимые для структурирования вывода дампа. Конечно, вы можете отображать содержимое структуры в отладчике, где такие метаданные хранятся в отладочной информации.
Кстати, вы спрашиваете о C или C ++? Эти два языка совершенно разные, как в функциях, так и в подходах, хотя ни один из них не имеет var_dump () или аналогичного.
C ++ сам по себе не предоставляет ничего подобного var_dump, но с такими библиотеками, как Boost.Fusion и ADAPT_STRUCT и ADAPT_ADT, это легко выполнимо.
В самом деле, как сказано в другом ответе, компилятор C ++ не генерирует метаданные, необходимые для создания такого вывода. Однако эти метаданные можно сгенерировать и использовать метапрограммирование шаблонов для их использования.
Таким образом, я реализовал здесь adapt_struct_printer, который может печатать std :: container, любые классы или структуры, boost :: variant и boost :: tuple.
Теперь вы можете легко сделать следующее:
#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;
Вы можете обратно с этой библиотекой также сделать from_json для заполнения структур из json.
Документацию можно найти здесь: http://daminetreg.github.io/lib-cpp-pre/html/namespacepre_1_1json.html#a4325d2cdd64a7e321303fd4428f298b9
Единственное требование – вы вызываете BOOST_FUSION_ADAPT_STRUCT / BOOST_FUSION_ADAPT_ADT на своих классах (см. http://www.boost.org/doc/libs/1_57_0/libs/fusion/doc/html/fusion/adapted.html )
Итак, чтобы этот пример:
#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; }
Распечатывает следующее:
{ 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, }
Я улучшаю реализацию, чтобы получить ее в какой-то момент как возможную новую функцию в boost fusion, но она уже используется, как показано на рисунке:
Нет, вам нужно катиться самостоятельно, используя один из семейства выходных функций cout
или C style для пользовательских структур данных. Аналогично, для массивов (кроме строк в стиле C) вам придется перебирать все элементы и печатать каждый.
Нет, нет. Например, используйте отладчик, например, ddd . У большинства IDE есть один интегрированный.
Это возможно, но потребовалось бы много работы, если бы были включены символы отладки и все оптимизации были отключены. Также он был бы медленным и, возможно, не очень надежным [* 1].
Все, что может сделать отладчик, может быть реплицировано функцией dump (), которая вызывает точку останова и выведенную из системы информацию.
Некоторые отладчики могут быть автоматизированы, поэтому, возможно, сама функция дампа будет записана в отладчике.
* 1 Например, отладчики иногда сбой при работе с некоторыми точками останова. например, программа должна иметь точку останова и останавливать все потоки, прежде чем пытаться сбрасывать данные. например, программы, которые должны иметь дело с прерываниями в реальном времени, вероятно, не сработают. например, отладчик должен быть достаточно надежным, чтобы иметь дело с множеством точек останова и не вводить другие проблемы.
В статье Microsoft есть несколько решений:
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; }
и призыв к этому:
cout << "vector data: " << endl; print_collection(v);