Should I use printf in my C++ code?

2019-01-10 08:07发布

I generally use cout and cerr to write text to the console. However sometimes I find it easier to use the good old printf statement. I use it when I need to format the output.

One example of where I would use this is:

// Lets assume that I'm printing coordinates... 
printf("(%d,%d)\n", x, y);

// To do the same thing as above using cout....
cout << "(" << x << "," << y << ")" << endl;

I know I can format output using cout but I already know how to use the printf. Is there any reason I shouldn't use the printf statement?

19条回答
淡お忘
2楼-- · 2019-01-10 08:23

If you ever hope to i18n your program, stay away from iostreams. The problem is that it can be impossible to properly localize your strings if the sentence is composed of multiple fragments as is done with iostream.

Besides the issue of message fragments, you also have an issue of ordering. Consider a report that prints a student's name and their grade point average:

std::cout << name << " has a GPA of " << gpa << std::endl;

When you translate that to another language, the other language's grammar may need you to show the GPA before the name. AFAIK, iostreams has not way to reorder the interpolated values.

If you want the best of both worlds (type safety and being able to i18n), use Boost.Format.

查看更多
干净又极端
3楼-- · 2019-01-10 08:24

C++ streams are overrated, after all they're in fact just classes with an overloaded operator <<.
I've read many times that streams are the C++ way as printf is the C way, but they are both library features available in C++, so you should use what suits best.
I mostly prefer printf, but I've also used streams, which provide cleaner code and prevent you from having to match % placeholders to arguments.

查看更多
Explosion°爆炸
4楼-- · 2019-01-10 08:27

On the whole I agree (hate the << syntax especially if you need complex formatting)

But I should point out the safety aspects.

printf("%x",2.0f)
printf("%x %x",2)
printf("%x",2,2)

Probably won't be noticed by the compiler but could crash your app.

查看更多
老娘就宠你
5楼-- · 2019-01-10 08:30

Streams are the canonical way. Try making this code work with printf:

template <typename T>
void output(const T& pX)
{
    std::cout << pX << std::endl;
}

Good luck.

What I mean is, you can make operators to allow your types to be outputted to ostream's, and without hassle use it just like any other type. printf doesn't fit the the generality of C++, or more specifically templates.

There's more than usability. There's also consistency. In all my projects, I have cout (and cerr and clog) tee'd to also output to a file. If you use printf, you skip all of that. Additionally, consistency itself is a good thing; mixing cout and printf, while perfectly valid, is ugly.

If you have an object, and you want to make it output-able, the cleanest way to do this is overload operator<< for that class. How are you going to use printf then? You're going to end up with code jumbled with cout's and printf's.

If you really want formatting, use Boost.Format while maintaining the stream interface. Consistency and formatting.

查看更多
smile是对你的礼貌
6楼-- · 2019-01-10 08:31

You can get the best of both worlds with the fmt library which combines safety and extensibility of iostreams with usability and performance of (s)printf. Example:

std::string = fmt::format("The answer is {}", 42);

The library supports Python-like and printf format string syntax.

Disclaimer: I'm the author of the fmt library.

查看更多
Anthone
7楼-- · 2019-01-10 08:32

Use boost::format. You get type safety, std::string support, printf like interface, ability to use cout, and lots of other good stuff. You won't go back.

查看更多
登录 后发表回答