Home > Blockchain >  Print function in C similar to Python
Print function in C similar to Python

Time:12-29

I am trying to make a header file that makes it easy to learn C . I was wondering if there was any way to make a print function in C that behaved similar to the print function in Python which prints the data irrespective of the datatype or dimensions of the data passed to it.

I could make a function that could print any numeric types and strings using templates and function overloading. But I am struggling with vectors and arrays as they may be multi dimensional.

I could get it to print upto 3D vectors using this:

#include <iostream>
#include <vector>

template<typename T>
void printVector(const std::vector<T>& vec)
{
    for (const auto& element : vec)
        std::cout << element << ' ';
    std::cout << '\n';
}

template<typename T>
void printVector(const std::vector<std::vector<T>>& vec)
{
    for (const auto& innerVector : vec)
        printVector(innerVector);
}

int main()
{
    std::vector<int> vec1{ 1, 2, 3, 4, 5 };
    std::vector<std::vector<double>> vec2{ { 1.1, 2.2 }, { 3.3, 4.4 } };
    std::vector<std::vector<std::vector<char>>> vec3{ { { 'a', 'b' }, { 'c', 'd' } }, { { 'e', 'f' }, { 'g', 'h' } } };

    printVector(vec1);
    printVector(vec2);
    printVector(vec3);

    return 0;
}

CodePudding user response:

You can do something like this:

#include <iostream>
#include <vector>
#include <map>

namespace detail {
    template<typename T>
    void printImpl(const T& o)
    {
        std::cout << o;
    }

    template<typename T>
    void printImpl(const std::vector<T>& vec)
    {
        char sep = '{';
        for (const auto& innerVector : vec) {
            std::cout << sep;
            printImpl(innerVector);
            sep = ',';
        }
        std::cout << "}";
    }

    template<typename K, typename V>
    void printImpl(const std::map<K, V>& cont)
    {
        char sep = '{';
        for (auto&& [k, v] : cont) {
            std::cout << sep;
            printImpl(k);
            std::cout << ":";
            printImpl(v);
            sep = ',';
        }
        std::cout << "}";
    }
}

template<typename... Args>
void print(Args&&... args)
{
    (detail::printImpl(std::forward<Args>(args)), ...);
}

int main()
{
    std::vector<int> vec1{ 1, 2, 3, 4, 5 };
    std::vector<std::vector<double>> vec2{ { 1.1, 2.2 }, { 3.3, 4.4 } };
    std::vector<std::vector<std::vector<char>>> vec3{ { { 'a', 'b' }, { 'c', 'd' } }, { { 'e', 'f' }, { 'g', 'h' } } };
    std::map<int, std::string> m{{0, "a"},{1, "b"}};

    print(vec1,"\n");
    print(vec2,"\n");
    print(vec3,"\n");
    print(m,"\n");

    return 0;
}

And specialize detail::printImpl() for any type for which you don't like default operator <<() behavior.

  • Related