Printf or cout?

Mar 17, 2017 at 10:31am
Hello,

I have been wondering if there is any alternative to printf in c++?

I find it very welcome that you can output text pretty fast and easy with it

 
printf("Hello, %d is the half of %d!\n", 2, 4);


instead of

 
cout << "Hello, " << 2 << " is the half of " << 4 << "!" << endl;



but unfortunately I do not think that printf is the way to go nowadays as you have to convert strings as example to c_str first, is there any other method that is able to output variables using % ?
Last edited on Mar 17, 2017 at 10:31am
Mar 17, 2017 at 11:55am
you could roll your own print() function I suppose if you really wanted to but in C++ std::cout is the best way to proceed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <string>

struct print
{
    template<typename T>
    print& operator,(const T& v)
    {
        std::cout << v << " ";
        return *this;
    }
};
int main()
{
    int a = 2;
    int b = 4;
    std::string c = "\nhello world";

    print(), "hello", a, "is the half of", b;
    print(), c;
}
Mar 17, 2017 at 12:08pm
printf works just fine in c++ programs for most simple things and can be cleaner, as you noted. cout is preferred for object oriented coding and pure c++, but printf IMHO is cleaner for printing loads of doubles or simple text and I use it when it seems useful. Extracting a char* from a string isn't that hard, but if you have a string already, cout << string << endl; done. Or cout << string1+string2<<endl; Printf shines for doubles, really, that setw stuff is garbage to me.



Last edited on Mar 17, 2017 at 12:11pm
Mar 17, 2017 at 12:36pm
one issue with printf() is that it can't be overloaded for custom types directly
Mar 17, 2017 at 12:50pm
With the new variadic template features in C++ it should be possible to write safe alternatives for printf that works correctly with user defined types and that fails graciously if the format doesn't match the arguments. Someone might have written something like this already, but all I know is that it's not part of the standard library.
Mar 17, 2017 at 1:36pm
Someone might have written something like this already

I think the most popular single-purpose non-standard formatting library today is fmtlib: https://github.com/fmtlib/fmt
Last edited on Mar 17, 2017 at 1:39pm
Mar 17, 2017 at 2:11pm
Someone might have written something like this already

It is in Stroustrup's book (The C++ Programming Language, 4th Ed) - and you are absolutely right @Peter87 - it is the precise example he uses to introduce variadic templates.
Mar 18, 2017 at 2:24am
I'm trying to make a variadic template print function with fold expression but the arguments are printed without space or newline characters - any suggestions?:
1
2
3
4
5
template<typename ...Args>
void printer(Args&&... args) {
    (std::cout << ... << args) << " " << '\n';
    //std::cout << " " << "\n";//doesn't work either
}

gcc 6.2, windows 8
Mar 18, 2017 at 3:01am
you could fold over the comma:
((std::cout << args << ' '), ...) << '\n';
Mar 18, 2017 at 4:20am
cubbi - the problem persists and reading up online I came across this from cire that seems to be the issue:

The fold expression with a binary operator is just meant to be a chain of those operators separating the arguments with nothing intervening (with an initial or trailing value.)

http://www.cplusplus.com/forum/general/193855/#msg932308
the workaround is as s/he suggested on that post:
1
2
3
4
5
6
template<typename ...Args>
void print(Args&&... args)
{
   auto print_elem = [](auto a){std::cout << a << "\n";};
   (print_elem(args), ...);
}

in fact http://en.cppreference.com/w/cpp/language/fold has a very similar example to my earlier non-working example with same results
Last edited on Mar 18, 2017 at 4:22am
Mar 18, 2017 at 4:40am
Folding over the sequencing operator works with clang++ 3.8 and g++ 6.3
http://coliru.stacked-crooked.com/a/9068ebbdf1ade8f5
Topic archived. No new replies allowed.