printf 与 std::cout
可能的重复:
我应该在 C++ 代码中使用 printf 吗?
如果我只是想要在屏幕上打印 string
,我可以使用这两种方式来做到这一点:
printf("abc");
std::cout << "abc" << std::endl;
情况是,在上面显示的示例中,使用 printf
是否有优势std::cout
,或者反之亦然?
Possible Duplicate:
Should I use printf in my C++ code?
If I just want to print a string
on screen, I can do that using those two ways:
printf("abc");
std::cout << "abc" << std::endl;
The case is, and in the examples shown above, is there an advantage of using printf
over std::cout
, or, vice versa?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
虽然
cout
是正确的 C++ 方式,但我相信某些人和公司(包括 Google)继续在 C++ 代码中使用printf
,因为使用printf
比使用cout 进行格式化输出要容易得多
。这是我在此处找到的一个有趣的示例。
比较:
和
While
cout
is the proper C++ way, I believe that some people and companies (including Google) continue to useprintf
in C++ code because it is much easier to do formatted output withprintf
than withcout
.Here's an interesting example that I found here.
Compare:
and
printf
及其关联的朋友是 C 函数。它们在 C++ 中工作,但不具有 C++ 的类型安全std::ostream
s。使用 printf 函数根据用户输入(甚至文件输入)格式化输出的程序中可能会出现问题。例如:C++ 具有更强的类型安全性(以及
std::string
类)来帮助防止此类问题。printf
and its associated friends are C functions. They work in C++, but do not have the type safety of C++std::ostream
s. Problems can arise in programs that useprintf
functions to format output based on user input (or even input from a file). For example:C++ has much stronger type safety (and a
std::string
class) to help prevent problems like these.我自己也为这个问题而挣扎。 printf 通常更容易用于格式化打印,但 C++ 中的 iostreams 工具有一个很大的优点,即您可以为对象创建自定义格式化程序。我最终根据需要在我的代码中使用了它们。
使用两者并混合使用它们的问题是 printf 和 cout 使用的输出缓冲区不相同,因此除非运行无缓冲或显式刷新输出,否则最终可能会导致输出损坏。
我对 C++ 的主要反对意见是,没有类似于 printf 的快速输出格式化工具,因此无法轻松控制整数、十六进制和浮点格式化的输出。
Java也有同样的问题;该语言最终得到了 printf。
维基百科对此问题进行了很好的讨论 http://en.wikipedia.org/ wiki/Printf#C.2B.2B_alternatives_to_sprintf_for_numeric_conversion。
I struggle with this very question myself. printf is in general easier to use for formatted printing, but the iostreams facility in C++ has the big advantage that you can create custom formatters for objects. I end up using both of them in my code as necessary.
The problem with using both and intermixing them is that the output buffers used by printf and cout are not the same, so unless you run unbuffered or explicitly flush output you can end up with corrupted output.
My main objection to C++ is that there is no fast output formatting facility similar to printf, so there is no way to easily control output for integer, hex, and floating point formatting.
Java had this same problem; the language ended up getting printf.
Wikipedia has a good discussion of this issue at http://en.wikipedia.org/wiki/Printf#C.2B.2B_alternatives_to_sprintf_for_numeric_conversion.
实际上,对于您的特定示例,您应该问一下 put 或 cout 哪个更可取。 printf 打印格式化文本,但您只是将纯文本输出到控制台。
对于一般用途,流(iostream,cout 是其中的一部分)更具可扩展性(您可以用它们打印您自己的类型),并且更通用,因为您可以生成函数来打印到任何类型的流,而不仅仅是控制台(或重定向输出)。您也可以使用 printf 创建通用流行为,使用 fprintf 将 FILE* 作为 FILE* 通常不是真正的文件,但这更棘手。
流是“类型安全”的,因为您会超载正在打印的类型。 printf 由于使用省略号而不是类型安全的,因此如果您放入与格式字符串不匹配的错误参数类型,您可能会得到未定义的结果,但编译器不会抱怨。如果您错过了一个参数或传入了一个错误的参数(例如 %s 的数字,并且无论如何它都将其视为指针),您甚至可能会遇到段错误/未定义的行为(但如果使用不正确,您可能会遇到 cout)。
不过 printf 确实有一些优点:您可以模板化格式字符串,然后为不同的数据重用该格式字符串,即使该数据不在结构中,并且对一个变量使用格式化操作不会“保留”该格式以供进一步使用,因为您指定每个变量的格式。 printf 也被认为是线程安全的,而 cout 实际上不是。
boost 将每种方法的优点与其 boost::format 库结合起来。
Actually for your particular example, you should have asked which is preferable, puts or cout. printf prints formatted text but you are just outputting plain text to the console.
For general use, streams (iostream, of which cout is a part) are more extensible (you can print your own types with them), and are more generic in that you can generate functions to print to any type of stream, not just the console (or redirected output). You can create generic stream behaviour with printf too using fprintf which take a FILE* as a FILE* is often not a real file, but this is more tricky.
Streams are "typesafe" in that you overload with the type you are printing. printf is not typesafe with its use of ellipses so you could get undefined results if you put the wrong parameter types in that do not match the format string, but the compiler will not complain. You may even get a seg-fault / undefined behaviour (but you could with cout if used incorrectly) if you miss a parameter or pass in a bad one (eg a number for %s and it treats it as a pointer anyway).
printf does have some advantages though: you can template a format string then reuse that format string for different data, even if that data is not in a struct, and using formatting manipulations for one variable does not "stick" that format for further use because you specify the format for each variable. printf is also known to be threadsafe whereas cout actually is not.
boost has combined the advantages of each with their boost::format library.
printf
是从 C 借用的,有一些限制。 printf 最常提到的限制是类型安全,因为它依赖程序员将格式字符串与参数正确匹配。可变参数环境再次带来的第二个限制是您无法使用用户定义的类型扩展行为。printf
知道如何打印一组类型,这就是您能从中得到的全部内容。尽管如此,对于它可以用来做的一些事情来说,使用printf
格式化字符串比使用 C++ 流更快、更简单。虽然大多数现代编译器能够解决类型安全限制并至少提供警告(编译器可以解析格式字符串并检查调用中提供的参数),但第二个限制无法克服。即使在第一种情况下,编译器也无法真正帮助解决某些问题,例如检查 null 终止 - 但话又说回来,如果您使用
std::cout
进行打印,也会出现同样的问题相同的数组。另一方面,流(包括 std::cout)可以通过重载的 std::ostream& 来扩展以处理用户定义的类型。对于任何给定的用户定义类型
type
,运算符<<( std::ostream&, type const & )。它们本身是类型安全的——如果您传入没有重载运算符<<的类型,编译器会抱怨。另一方面,它们生成格式化输出更加麻烦。那么你应该使用什么?一般来说,我更喜欢使用流,因为为我自己的类型重载运算符<<很简单,并且它们可以与所有类型统一使用。
The
printf
has been borrowed from C and has some limitations. The most common mentioned limitation ofprintf
is type safety, as it relies on the programmer to correctly match the format string with the arguments. The second limitation that comes again from the varargs environment is that you cannot extend the behavior with user defined types. Theprintf
knows how to print a set of types, and that's all that you will get out of it. Still, it for the few things that it can be used for, it is faster and simpler to format strings withprintf
than with c++ streams.While most modern compilers, are able to address the type safety limitation and at least provide warnings (the compiler can parse the format string and check the arguments provided in the call), the second limitation cannot be overcome. Even in the first case, there are things that the compiler cannot really help with, as checking for null termination --but then again, the same problem goes with
std::cout
if you use it to print the same array.On the other end, streams (including
std::cout
) can be extended to handle user defined types by means of overloadedstd::ostream& operator<<( std::ostream&, type const & )
for any given user defined typetype
. They are type safe by themselves --if you pass in a type that has no overloadedoperator<<
the compiler will complain. They are, on the other hand, more cumbersome to produce formatted output.So what should you use? In general I prefer using streams, as overloading
operator<<
for my own types is simple and they can be used uniformly with all types.这两个例子做了不同的事情。后者将添加换行符并刷新输出(std::endl 的结果)。
std::cout
也更慢。除此之外,printf
和std::cout
实现相同的功能,您可以选择您喜欢的任何一个。作为偏好问题,我会在 C++ 代码中使用std::cout
。它更具可读性并且更安全。如果您需要使用
std::cout
格式化输出,请参阅本文代码>.Those two examples do different things. The latter will add a newline character and flush output (result of
std::endl
).std::cout
is also slower. Other than that,printf
andstd::cout
achieve the same thing and you can choose whichever you prefer. As a matter of preference, I'd usestd::cout
in C++ code. It's more readable and safer.See this article if you need to format output using
std::cout
.一般来说,您应该更喜欢 cout,因为它类型更安全且更通用。 printf 不是类型安全的,也不是通用的。您可能喜欢 printf 的唯一原因是速度——从内存来看,printf 比 cout 快很多倍。
In general, you should prefer cout because it's much type-safer and more generic. printf isn't type-safe, nor is it generic at all. The only reason you might favour printf is speed- from memory, printf is many times faster than cout.