在C+中应使用哪个C I/O库+;密码? 如果像我一样,在学习C++之前学习C,STDIO库看起来更自然。IoStand与Stdio有利弊,但我在使用IoSturn.时忘记Prtff.()。在过去的日子里,C++标准委员会一直在用语言来解决问题,而IOFFASES是一个移动的目标。如果您使用iostreams,那么您就有机会每年左右重写部分代码。正因为如此,我一直使用stdio,自1989年以来,它没有发生显著变化

在C+中应使用哪个C I/O库+;密码? 如果像我一样,在学习C++之前学习C,STDIO库看起来更自然。IoStand与Stdio有利弊,但我在使用IoSturn.时忘记Prtff.()。在过去的日子里,C++标准委员会一直在用语言来解决问题,而IOFFASES是一个移动的目标。如果您使用iostreams,那么您就有机会每年左右重写部分代码。正因为如此,我一直使用stdio,自1989年以来,它没有发生显著变化,c++,iostream,stdio,C++,Iostream,Stdio,我注意到一些程序员似乎坚持使用stdio,坚持认为它更具可移植性 真的是这样吗?使用什么更好?< p>如果像我一样,在学习C++之前学习C,STDIO库看起来更自然。IoStand与Stdio有利弊,但我在使用IoSturn.时忘记Prtff.()。在过去的日子里,C++标准委员会一直在用语言来解决问题,而IOFFASES是一个移动的目标。如果您使用iostreams,那么您就有机会每年左右重写部分代码。正因为如此,我一直使用stdio,自1989年以来,它没有发生显著变化 如果我今天在做一些事

我注意到一些程序员似乎坚持使用stdio,坚持认为它更具可移植性


真的是这样吗?使用什么更好?

< p>如果像我一样,在学习C++之前学习C,STDIO库看起来更自然。IoStand与Stdio有利弊,但我在使用IoSturn.

时忘记Prtff.()。在过去的日子里,C++标准委员会一直在用语言来解决问题,而IOFFASES是一个移动的目标。如果您使用iostreams,那么您就有机会每年左右重写部分代码。正因为如此,我一直使用stdio,自1989年以来,它没有发生显著变化

如果我今天在做一些事情,我会使用iostreams。

太冗长了

考虑iostream构造以执行以下操作(类似于scanf):

这需要一些类似的东西:

std::cerr << "at " << static_cast<void*>(stats) << "/" << stats->name
          << ": mean value " << std::precision(3) << stats->mean
          << " of " << std::width(4) << std::fill(' ') << stats->sample_count
          << " samples " << std::endl;
// i18n UNSAFE 
std::cout << "Dear " << name.given << ' ' << name.family << std::endl;

std::cerr回答原始问题:
使用stdio可以完成的任何操作都可以使用iostream库完成。

Disadvantages of iostreams: verbose
Advantages    of iostreams: easy to extend for new non POD types.

前向C++的C型是安全的。

  • iostreams被设计为显式类型安全的。因此,对对象的赋值也会显式地检查被赋值对象的类型(在编译时)(如果需要,会生成编译时错误)。从而防止运行时内存过度运行或将浮点值写入char对象等。

  • 另一方面,scanf()/printf()和family依赖于程序员获得正确的格式字符串,并且没有类型检查(我相信gcc有一个扩展可以帮助)。因此,它是许多错误的根源(因为程序员在分析方面不如编译器完美[并不是说编译器比人类更完美])

只是为了澄清科林·詹森的评论

  • 自上一个标准发布以来,iostream库一直保持稳定(我忘记了实际年份,但大约是10年前)
澄清Mikael Jansson的评论

  • 他提到的其他使用格式样式的语言都有明确的保护措施,以防止C stdio库的危险副作用(在C语言中,但不是提到的语言中)导致运行时崩溃
注意:我同意iostream库有点冗长。但我愿意忍受冗长,以确保运行时的安全。但是我们可以通过使用

#包括
#包括
#包括
结构X
{//此结构是从
//由“Mikael Jansson”提供的示例,以使其成为一个运行示例
字符*名称;
双均值;
int样本计数;
};
int main()
{
X stats[]={{“Plop”,5.6,2};
//无意义的输出,只是举例说明
//标准版本
fprintf(标准,“在%p/%s时:平均值%.3f,共%4d个样本\n”,
统计,统计->名称,统计->平均值,统计->样本计数);
//流

std::cerr对于二进制IO,我倾向于使用stdio的fread和fwrite。对于格式化的内容,我通常会使用IO流,尽管正如Mikael所说,非繁琐(非默认?)的格式化可以是PITA。

stdio更适合读取二进制文件(如将块加载到向量中并使用.resize()等)。有关示例,请参见中file.hh中的read_rest函数


C++流在读取二进制文件时可能会阻塞大量字节,从而导致错误的eof。

为printf样式的字符串格式提供了一种类型安全、面向对象的替代方法,并且是iostreams的补充,iostreams不会因为巧妙地使用运算符%而遭受通常的详细性问题。我建议考虑使用plain C printf如果您不喜欢用iostream的操作符格式化,我使用iostreams,主要是因为这样以后更容易处理流(如果我需要的话)。例如,您可能会发现希望在某个跟踪窗口中显示输出—使用cout和cerr这相对容易。当然,您可以在unix上处理管道和其他内容,但这并不是可移植的


我确实喜欢printf格式,所以我通常先格式化字符串,然后将其发送到缓冲区。对于Qt,我经常使用(尽管他们建议改为使用)。我也看过了,但无法真正习惯语法(太多的%)。不过,我真的应该看一看。

既然iostreams已经成为一种标准,您应该使用它们,因为您的代码肯定能与较新版本的编译器一起工作。我想现在大多数编译器都非常了解iostreams,使用它们应该不会有任何问题


但是如果你想坚持使用*printf函数,我认为没有问题。

原则上我会使用iostreams,实际上我使用了太多的格式化小数等,这使得iostreams太不可读,所以我使用stdio.Boost::format是一种改进,但对我来说还不够激励。实际上,stdio几乎是类型安全的大多数现代编译器都进行参数检查


这是一个我仍然对任何解决方案都不满意的领域。

我错过了iOS库的格式化输入


iostreams没有复制scanf()的好方法即使Boost对输入没有必要的扩展。

< P>虽然C++的IONSWORKAPI有很多好处,但是一个重要的问题是I18N附近。问题是参数替换的顺序可以根据文化而变化。
std::cerr << "at " << static_cast<void*>(stats) << "/" << stats->name
          << ": mean value " << std::precision(3) << stats->mean
          << " of " << std::width(4) << std::fill(' ') << stats->sample_count
          << " samples " << std::endl;
// i18n UNSAFE 
std::cout << "Dear " << name.given << ' ' << name.family << std::endl;
//i18n不安全

STD::CUT< P>我将比较两个主流库,从C++标准库。

C++中不应该使用C样式窗体-基于字符串的字符串处理例程。 限制其使用存在以下几个原因:

  • 不安全
  • // foo.h
    ...
    float foo;
    ...
    
    // bar/frob/42/icetea.cpp
    ...
    scanf ("%f", &foo);
    ...
    
    // foo.h
    ...
    FixedPoint foo;
    ...
    
    // bar/frob/42/icetea.cpp
    ...
    scanf ("%f", &foo);
    ...
    
      printf ("My Matrix: %f %f %f %f\n"
              "           %f %f %f %f\n"
              "           %f %f %f %f\n"
              "           %f %f %f %f\n",
              mat(0,0), mat(0,1), mat(0,2), mat(0,3), 
              mat(1,0), mat(1,1), mat(1,2), mat(1,3), 
              mat(2,0), mat(2,1), mat(2,2), mat(2,3), 
              mat(3,0), mat(3,1), mat(3,2), mat(3,3));
    
    cout << mat << '\n';
    
    printf ("Guten Morgen, Sie sind %f Meter groß und haben %d Kinder", 
            someFloat, someInt);
    
    printf ("Good morning, you have %d children and your height is %f meters",
            someFloat, someInt); // Note: Position changed.
    
    // ^^ not the best example, but different languages have generally different
    //    order of "variables"
    
    cout << format("%1% %2% %3% %2% %1% \n") % "11" % "22" % "333"; // 'simple' style.
    
    shared_ptr<float> f(new float);
    fscanf (stdout, "%u %s %f", f)
    
    const char *output = "in total, the thing is 50%"
                         "feature  complete";
    printf (output);