C++ printf与std::cout

C++ printf与std::cout,c++,printf,cout,C++,Printf,Cout,可能重复: 如果我只想在屏幕上打印字符串,我可以使用以下两种方法: printf("abc"); std::cout << "abc" << std::endl; printf(“abc”); 这两个例子做了不同的事情。后者将添加一个换行符并刷新输出(std::endl的结果)标准::cout也较慢。除此之外,printf和std::cout实现了相同的功能,您可以选择您喜欢的功能。作为首选,我将使用 STD::CUT C++代码。它更具可读性和安全性 查看是否需要

可能重复:

如果我只想在屏幕上打印
字符串
,我可以使用以下两种方法:

printf("abc");

std::cout << "abc" << std::endl;
printf(“abc”);

这两个例子做了不同的事情。后者将添加一个换行符并刷新输出(std::endl的结果)<代码>标准::cout
也较慢。除此之外,
printf
std::cout
实现了相同的功能,您可以选择您喜欢的功能。作为首选,我将使用<代码> STD::CUT C++代码。它更具可读性和安全性


查看是否需要使用
std::cout

格式化输出。一般来说,您应该更喜欢cout,因为它更安全、更通用。printf不是类型安全的,也不是通用的。你可能喜欢PrTNF的唯一原因是内存速度,PrimTf比CUT快很多倍。

< P>而 CUT是正确的C++方式,我相信有些人和公司(包括)在C++代码中继续使用<代码> Primtf<代码>,因为使用<代码> Prtff<代码>比用<代码> CUT更容易进行格式化输出。 我发现了一个有趣的例子

比较:

printf( "%-20s %-20s %5s\n" , "Name" , "Surname" , "Id" );

cout及其关联的友元是C函数。它们在C++中工作,但没有C++的类型安全性。使用
printf
函数根据用户输入(甚至文件输入)格式化输出的程序可能会出现问题。例如:

int main()
{
    char[] a = {'1', '2', '3', '4'}; // a string that isn't 0-terminated
    int i = 50;
    printf("%s", a); // will continue printing characters until a 0 is found in memory
    printf("%s", i); // will attempt to print a string, but this is actually an integer
}

C++具有更强的类型安全性(以及一个
std::string
类),有助于防止此类问题。

实际上,对于您的特定示例,您应该询问哪个更可取,put还是cout。printf打印格式化文本,但您只是将纯文本输出到控制台

对于一般用途,流(iostream,cout是其中的一部分)更具可扩展性(您可以使用它们打印自己的类型),并且更通用,因为您可以生成打印到任何类型流的函数,而不仅仅是控制台(或重定向输出)。您也可以使用fprintf创建printf的通用流行为,fprintf将文件*作为文件*通常不是真正的文件,但这更复杂

流是“类型安全”的,因为您打印的类型会过载。printf使用省略号并不是类型安全的,因此如果您在其中输入了与格式字符串不匹配的错误参数类型,则可能会得到未定义的结果,但编译器不会抱怨。如果您错过了一个参数或传入了一个错误的参数(例如%s的一个数字,它将它视为一个指针),您甚至可能会得到一个seg错误/未定义的行为(但如果使用不正确,您可以使用cout)

printf确实有一些优点:您可以对格式字符串进行模板化,然后对不同的数据重用该格式字符串,即使该数据不在结构中,并且对一个变量使用格式操作不会“粘贴”该格式以供进一步使用,因为您为每个变量指定了格式。printf也被认为是线程安全的,而cout实际上不是


boost将它们各自的优点与boost::format库结合起来。

我自己也在努力解决这个问题。PrtfF通常更容易用于格式化打印,但是C++中的IoStices设施具有很大的优势,您可以为对象创建自定义格式。我最终会在必要时在代码中同时使用它们

使用两者并混合使用它们的问题在于printf和cout使用的输出缓冲区不同,因此除非运行无缓冲或显式刷新输出,否则最终可能会导致输出损坏

<我的主要反对意见是C++没有类似于PrtTf的快速输出格式化工具,所以没有办法轻易地控制整数、十六进制和浮点格式的输出。 Java也有同样的问题;这种语言最终得到了printf


Wikipedia在上对这个问题进行了很好的讨论。

printf
是从C借来的,有一些限制。
printf
最常见的限制是类型安全,因为它依赖于程序员将格式字符串与参数正确匹配。varargs环境的第二个限制是不能使用用户定义的类型扩展行为。
printf
知道如何打印一组类型,这就是您将从中获得的全部内容。不过,对于它所能使用的一些东西,用 Prtff比用C++流来格式化字符串更快、更简单。 虽然大多数现代编译器都能够解决类型安全限制并至少提供警告(编译器可以解析格式字符串并检查调用中提供的参数),但第二个限制无法克服。即使在第一种情况下,编译器也无法真正帮助您解决一些问题,比如检查空终止——但是,如果您使用
std::cout
打印相同的数组,同样的问题也会出现


另一方面,流(包括<代码> STD::CUT)可以扩展到处理用户定义的类型,通过重载<代码> STD::OFSUCTORATOR。如果你正在编写C++代码,那么你应该更喜欢C++的习语和库。这取决于你用C语言编写的程序,还是C++语言。这两种方法的语言不同,所以你不能直接比较。@Paul R。谢谢你的回答。那么,“Prtff()”不是被认为是C++习语吗?谢谢你的回复。我用C++,谢谢你的回复。我看到“printf()”启用了格式化,“cout”也提供了格式吗?当你说:“printf不是类型安全的,也不是泛型的。你支持printf的唯一原因是速度——从内存来看,printf比cout快很多倍。”?你能不能把那件事说清楚一点。谢谢。@aali:cout还提供outpu

int main()
{
    char[] a = {'1', '2', '3', '4'}; // a string that isn't 0-terminated
    int i = 50;
    printf("%s", a); // will continue printing characters until a 0 is found in memory
    printf("%s", i); // will attempt to print a string, but this is actually an integer
}