在新的C++代码中,我倾向于使用C++ iostream库而不是C stdio库.
我注意到一些程序员似乎坚持stdio,坚持认为它更便携.
这是真的吗?有什么好用的?
回答原始问题:
可以使用iostream库完成使用stdio完成的任何操作.
Disadvantages of iostreams: verbose Advantages of iostreams: easy to extend for new non POD types.
通过C制作的C++的前进是类型安全.
iostreams被设计为明确类型安全.因此,对象的赋值也明确地检查了所分配对象的类型(在编译器时)(如果需要,则生成编译时错误).从而防止运行时内存溢出或将浮点值写入char对象等.
另一方面,scanf()/ printf()和family依赖于程序员正确的格式字符串,并且没有类型检查(我相信gcc有一个帮助的扩展).因此,它是许多错误的根源(因为程序员的分析不如编译器完美[不会说编译器完美只比人类更好]).
只是为了澄清Colin Jensen的评论.
自上一个标准发布以来,iostream库一直保持稳定(我忘记了实际的年份,但大约10年前).
澄清Mikael Jansson的评论.
他提到使用格式样式的其他语言有明确的安全措施来防止C stdio库的危险副作用(可能是C语言而不是上述语言)导致运行时崩溃.
NB我同意iostream库有点冗长.但我愿意忍受冗长以确保运行时安全.但是我们可以通过使用Boost格式库来减轻冗长.
#include#include #include struct X { // this structure reverse engineered from // example provided by 'Mikael Jansson' in order to make this a running example char* name; double mean; int sample_count; }; int main() { X stats[] = {{"Plop",5.6,2}}; // nonsense output, just to exemplify // stdio version fprintf(stderr, "at %p/%s: mean value %.3f of %4d samples\n", stats, stats->name, stats->mean, stats->sample_count); // iostream std::cerr << "at " << (void*)stats << "/" << stats->name << ": mean value " << std::fixed << std::setprecision(3) << stats->mean << " of " << std::setw(4) << std::setfill(' ') << stats->sample_count << " samples\n"; // iostream with boost::format std::cerr << boost::format("at %p/%s: mean value %.3f of %4d samples\n") % stats % stats->name % stats->mean % stats->sample_count; }
它太冗长了.
思考iostream构造以执行以下操作(类似于scanf):
// nonsense output, just to examplify fprintf(stderr, "at %p/%s: mean value %.3f of %4d samples\n", stats, stats->name, stats->mean, stats->sample_count);
这将需要类似的东西:
std::cerr << "at " << static_cast(stats) << "/" << stats->name << ": mean value " << std::precision(3) << stats->mean << " of " << std::width(4) << std::fill(' ') << stats->sample_count << " samples " << std::endl;
字符串格式化是一种情况,面向对象可以而且应该回避有利于嵌入字符串的格式化DSL.考虑Lisp format
,Python的printf样式格式,或PHP,Bash,Perl,Ruby及其字符串插值.
iostream
因为这个用例充其量是错误的.
该升压格式库提供了printf风格的字符串格式化一个类型安全的,面向对象的替代品,到不从通常的冗长的问题遭受输入输出流的补充,由于巧妙地利用运营商%.如果您不喜欢使用iostream的operator <<进行格式化,我建议您考虑使用普通的C printf.
回到过去的糟糕时期,C++标准委员会一直在使用该语言,而iostreams则是一个不断变化的目标.如果您使用了iostream,那么您每年都有机会重写部分代码.因此,我总是使用自1989年以来没有显着变化的stdio.
如果我今天做的事情,我会使用iostreams.
如果像我一样,你在学习C++之前学过C,那么stdio库似乎更自然.iostream与stdio有利有弊,但在使用iostream时我确实错过了printf().
原则上我会使用iostreams,在实践中我做了太多格式化的小数等,使得iostreams太难以理解,所以我使用了stdio.Boost :: format是一种改进,但对我来说还不够激励.在实践中,stdio几乎是类型安全的,因为大多数现代编译器无论如何都会进行参数检查.
这是一个我仍然不满意任何解决方案的领域.