我应该切换到C++;I/O流? 我从未使用过C++的I/O流,总是选择我所知道的。 i、 e.printf函数

我应该切换到C++;I/O流? 我从未使用过C++的I/O流,总是选择我所知道的。 i、 e.printf函数,c++,iostream,C++,Iostream,我知道使用I/O流有一些好处,但我正在寻找一些技巧 来自stackoverflow社区,帮助我(或说服我)切换。因为我还是 我更喜欢printf,我认为printf风格更容易阅读,打字也更快 即使我仍然继续使用printf,我仍然希望熟悉它 编辑。有趣的是,谷歌C++编码风格禁止使用流,除了日志记录。 见: 流 仅将流用于日志记录。定义:流是一种 替换printf()和scanf() 优点:使用流,您不需要知道所需对象的类型 我们正在印刷。您在格式化字符串方面没有问题 匹配参数列表。(虽然有g

我知道使用I/O流有一些好处,但我正在寻找一些技巧 来自stackoverflow社区,帮助我(或说服我)切换。因为我还是 我更喜欢printf,我认为printf风格更容易阅读,打字也更快

即使我仍然继续使用printf,我仍然希望熟悉它


编辑。有趣的是,谷歌C++编码风格禁止使用流,除了日志记录。 见:

仅将流用于日志记录。定义:流是一种 替换printf()和scanf()

优点:使用流,您不需要知道所需对象的类型 我们正在印刷。您在格式化字符串方面没有问题 匹配参数列表。(虽然有gcc,但您没有 printf也有问题。)流具有自动构造函数和 用于打开和关闭相关文件的析构函数

缺点:流使得像pread()这样的功能很难实现。一些 格式设置(特别是常用格式字符串习惯用法%.*s)是 如果不是不可能,也很难有效地使用流 使用类似printf的黑客。流不支持运算符重新排序 (%1s指令),这有助于国际化

决策:除非日志记录需要,否则不要使用流 接口。改用类似printf的例程

使用流有各种各样的优点和缺点,但在本例中 在许多其他情况下,一致性压倒了辩论。不要使用流 在你的代码中

扩展讨论

在这个问题上有过争论,所以这解释了 更大的深度。回想一下唯一的单向指导原则:我们要 确保每当我们执行某种类型的I/O时,代码看起来 所有这些地方都是一样的。因此,我们不想允许 用户可以选择使用streams还是printf plus 读/写/等等。相反,我们应该选择其中之一。我们做了 日志记录是一个例外,因为它是一个非常专门的 应用程序,以及历史原因

溪流的支持者认为溪流是显而易见的选择 这两个问题中的一个,但问题实际上并不那么清楚。每 他们指出,溪流的优势在于,有一个等价物 缺点最大的优点是你不需要知道 要打印的对象的类型。这是一个公平的观点。但是 有一个缺点:您很容易使用错误的类型,而 编译器不会警告您。这种错误很容易犯 不知道何时使用流

cout << this;  // Prints the address 
cout << *this;  // Prints the contents 

<代码> cOUT> p>不能用新的格式说明符扩展<代码> Prtff<代码>来处理自己的类型。

您可以避免对C++ I/O流的类型错误的保护,但它们很慢。因此,这主要取决于性能的重要性


I/O流也是多态的,与C stdio函数不同,流的用户不需要知道它是否连接到控制台、文件或其他逻辑。但这对于大多数应用程序来说并不重要。

iostreams提供的巨大优势是安全性。printf()是一个固有的不安全函数。不仅如此,重载使用boost::format也很简单。它兼备了这两个方面的优点。

我自己不是流的大用户,所以我只列出我对它们的看法。这确实是主观的,如果我的答案被投票删除,我会理解的

  • 我喜欢:同质性

我可能有一个
枚举
、一个
或其他任何东西,通过提供相同的
操作符@Matt,我支持您,使我的用户定义类型始终可打印。我一直讨厌溪流。当然,我可以用。让他们做我想做的任何事。但是我喜欢printf,因为我更喜欢语法

我甚至编写了一个
strprintf
,它的工作原理与
sprintf
完全相同,只是返回了一个
std::string
,而不是写入字符缓冲区

但渐渐地,我几乎完全停止使用
sprintf
。因为,简单地说,我写了太多该死的错误,我厌倦了一遍又一遍地重复我的错误
stringstream
s type safety让我远离自己

我所说的bug有两种形式,主要是:

  • 我为输出缓冲区选择了错误的幻数。假设我想出了
    charbuf_256]
    来格式化一些小东西。好吧,就像比尔·盖茨(Bill Gates)的著名评论“256KB的内存应该足够任何人使用”一样,我的错误低到足以引起我的注意。另一方面,我该怎么办<代码>字符大小[1024*64]
  • ?极端,但你明白了。没有完美的幻数。您要么让自己面临更多的崩溃,要么浪费内存

  • sprintf
    -编辑了一个字符串,但发送了一个浮点。一直这样做。嗯,不总是这样。对于每100次调用
    sprintf
    ,我可能会这样做一两次。对于生产代码,这是很多

  • 有了溪流,这两种情况都不会发生。所以我现在使用流,我的代码从不崩溃。好。。。无论如何,在那里

    有人会说流比sprintf慢。呃,也许吧。为了论证起见,我甚至会同意。不过没什么大不了的。我在实时股票市场服务器上工作,这些服务器每天每秒例行处理300万条消息。我从来没有遇到过水流速度的问题。也许会慢一点,但我还有更重要的事要做。

    cerr << "Error connecting to '" << foo->bar()->hostname.first
         << ":" << foo->bar()->hostname.second << ": " << strerror(errno);
    fprintf(stderr, "Error connecting to '%s:%u: %s",
          foo->bar()->hostname.first, foo->bar()->hostname.second,
          strerror(errno)); 
    
    std::ostream &operator<<(std::ostream &, const MyType &);
    
    std::cout << std::left << std::fixed << std::setprecision(0) << f << std::endl;