C++是否可以将fstream对象设置为在每次调用<<



我创建了一个fstream对象来将信息写入文件。我像一样将字符串写入新文件

fStreamObject << "New message.n";

因为我想要每个<lt;将字符串打印到下一行。

我希望能够设置一个属性并像一样拨打电话

fstreamObject << "New message.";

它将把字符串写入下一行。

fstream对象是否有允许这样做的标志/设置?

我已经看到了不同的文件模式(即:stream::in,ofstream::out等),但我找不到一个能自动写入新行的模式。此外,我不想写我自己的解决方案。我希望能够使用内置功能。

不,在标准流中没有这种易于配置的功能。

您可能需要对流类型进行子类化,并摆弄operator<<以使其按您想要的方式工作,或者使用某种描述的辅助函数:

fstreamObject << nl("New message.");

(但这很难比只在其中包含n(无论如何,对于字符串)更容易。

这取决于"设置流"的含义。如果我们认为这是相当宽泛的,那么答案恰好是"是"!

方法如下:

  1. 创建一个流缓冲区,在每次刷新时(即调用sync()时)插入一个换行符。否则,它只是转发字符
  2. 将文件流的流缓冲区更改为使用此流缓冲区过滤文件流的缓冲区
  3. 设置标志std::ios_base::unitbuf,该标志会在每次[正确写入]输出操作后导致刷新

以下是这样做的示例代码:

#include <iostream>
class newlinebuf
    : public std::streambuf {
    std::ostream*   stream;
    std::streambuf* sbuf;
    int overflow(int c) { return this->sbuf->sputc(c); }
    int sync() {
        return (this->sbuf->sputc('n') == std::char_traits::eof() 
                || this->sbuf->pubsync() == -1)? -1: 0;
    }
public:
    newlinebuf(std::ostream& stream)
        : stream(&stream)
        , sbuf(stream.rdbuf(this)) {
        stream << std::unitbuf;
    }
    ~newlinebuf() { this->stream->rdbuf(this->sbuf); }
};
int main() {
    newlinebuf sbuf(std::cout);
    std::cout << "hello" << "world";
}

虽然这种方法有效,但我建议不要使用它!问题是,所有的复合输出操作符,即使用多个输出操作符来完成工作的操作符,都会导致多个换行符。我不知道可以采取什么措施来防止这种行为。标准库中没有任何东西可以只配置流来实现这一点:您需要以某种方式插入换行符。

不,C++流不允许这样做
无法决定一次插入在哪里停止,下一次插入从哪里开始
例如,对于自定义类型,它们的流插入器通常被实现为对其他流插入器和成员函数的调用。

唯一能做的事情就是编写自己的类,该类委托给您选择的流,并执行此操作
不过,这是非常有限的效用。

struct alwaysenter {
     std::ostream& o;
     template<class X> alwaysenter& operator<<(X&& x) {
         o<<std::forward<X>(x);
         return *this;
     }
};

相关内容

最新更新