C++ Streams与C风格的IO?

gab*_*lin 26 c++ io printf iostream

我编码一些C++的小爱好的项目时,我注意到,我使用C风格的操作来访问IO( ,printf,fopen等).

在C++项目中涉及C函数是否被认为是"不良做法"?使用流而不是C风格的IO访问有什么好处?

Syl*_*sne 40

这是一个热门话题.

有些人更喜欢使用C++ IO,因为它们是类型安全的(你不能在对象的类型和格式字符串中指定的类型之间存在分歧),并且使用C++的其余编码方式更自然地流动.

但是,还有C IO功能的论据(我个人的最爱).他们之中有一些是:

  • 它们更容易与本地化集成,因为整个字符串本地化不会在较小的字符串中分解,并且通过一些实现,本地化程序可以重新排序插入值的顺序,将它们移动到字符串中,...
  • 您可以直接查看将要写入的文本的格式(对于流操作符,这可能非常困难).
  • 由于没有内联,只有一个printf函数实例,生成的代码更小(这在嵌入式环境中很重要).
  • 在某些实现中比C++函数更快.

就个人而言,我不认为在C++代码中使用C流是不好的做法.有些组织甚至建议在C++流上使用它们.我认为糟糕的风格是在同一个项目中使用两者.一致性是我认为的关键.


正如其他人所指出的,在一个相对较大的项目中,你可能不会直接使用它们,但你会使用一组最适合你的编码标准和你的需求的包装函数(或类)(本地化,类型安全, ...).您可以使用一个或另一个IO接口来实现此更高级别的接口,但您可能只使用一个.


编辑:添加有关printf格式化函数系列与本地化相关的优势的一些信息.请注意,这些信息仅适用于某些实施.

您可以使用%m$而不是%按索引引用参数,而不是按顺序引用它们.这可用于重新排序格式化字符串中的值.以下程序将Hello World!在标准输出上写入.

#include <stdio.h>
int main() {
    printf("%2$s %1$s\n", "World!", "Hello");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

考虑翻译这个C++代码:

if (nb_files_deleted == 1)
    stream << "One file ";
else
    stream << nb_file_deleted << " files ";
stream << removed from directory \"" << directory << "\"\n";
Run Code Online (Sandbox Code Playgroud)

这可能真的很难.使用printf(和类似gettext处理本地化的库),代码不与字符串混合.因此,我们可以将字符串传递给本地化团队,如果在某种语言中存在特殊情况,则不必更新代码(在某种语言中,如果对象的数量为0,则使用复数形式,在其他语言中,有三种形式,一种是单数形式,一种是有两种物体,一种是复数形式,......).

printf (ngettext ("One file removed from directory \"%2$s\"",
                  "%1$d files removed from directory \"%2$s\"",
                  n),
        n, dir);
Run Code Online (Sandbox Code Playgroud)

  • 本地化子弹+1.但是,如何重新排序printf中的值? (2认同)
  • 我已经更新了我的帖子,解释了如何重新排序`printf`中的值(提示:`%m $`). (2认同)

Pup*_*ppy 8

printf和朋友相比<iostream>,并且不能扩展,显然是不安全的,加上当然fopen和朋友没有RAII,这意味着除非你用探查器证明你肯定需要性能差异(你已证明存在于你的平台上)在你的代码中,你必须是个白痴printf.

编辑:本地化是一个有趣的事情,我没有考虑过.我从来没有本地化的任何代码,并不能在相对localizational能力发表意见printf<iostream>

  • AFAIK,基本本地化是通过从程序中提取字符串文字(被调用翻译函数包围)并让人们翻译这些字符串来完成的.想象一下,必须从cout中获得的句子片段中翻译和构造有意义的句子. - 尽管如此,Boost.Format可以帮助你解决这个问题. (4认同)

Nem*_*vic 6

对于一个小型的业余爱好项目,我可能会选择更安全的C++ io流.

有趣的是,我从未见过使用其中任何一个的非平凡的现实生活项目.在所有情况下,我们都使用了一些基于本机OS API构建的抽象来实现IO.


Arm*_*yan 5

如果它有明确的目的,那么没有什么可以被认为是不好的做法.我的意思是,如果IO是程序的瓶颈,那么是的,C风格的IO比C++ IO工作得更快.但如果不是,我会采用C++流方法.因为这是可爱的:)


Mik*_*our 5

好处

  • 类型安全:在编译时检查C++流操作的参数类型,而如果它们与格式不匹配printf则传递参数...导致未定义的行为.
  • 资源管理:C++流对象有析构函数来关闭文件句柄,空闲缓冲区以及你有什么.C流要求你记得打电话fclose.

缺点

  • 性能:当然,这取决于实现,但我发现使用C++流的printf格式要比等效格式慢得多.