如何将非null终止的字符串输出到iostream,但保持格式

时间:2018-07-05 14:15:18

标签: c++ iostream

我正在尝试输出非null终止字符串,但保持iomanip格式,例如std :: left,std :: setw等。

我当前的代码如下:

inline std::ostream& operator << (std::ostream& os, const StringRef &sr){
    //return os.write(sr.data(), sr.size() );
    // almost the same, but std::setw() works
    return __ostream_insert(sr.data(), sr.size() );
}

在具有gcc的Linux上可以正常运行,但在具有clang的MacOS上无法运行。

1 个答案:

答案 0 :(得分:1)

关于os.rdbuf()->sputn(seq, n)的建议当然很有趣,但并未取得预期的结果。

我确实打开了GCC C ++库代码并从那里“偷了”。清理后,代码是这样的:

inline std::ostream& operator << (std::ostream& os, const StringRef &sr){
    // following is based on gcc __ostream_insert() code:
    // https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.2/ostream__insert_8h-source.html

    std::streamsize const width = os.width();
    std::streamsize const size  = static_cast<std::streamsize>( sr.size() );
    std::streamsize const fill_size = width - size;

    bool const left = (os.flags() & std::ios::adjustfield) == std::ios::left;

    auto osfill = [](std::ostream& os, auto const count, char const c){
        for(std::streamsize i = 0; i < count; ++i)
            os.put(c);
    };

    if (fill_size > 0 && left == false)
        osfill(os, fill_size, os.fill());

    os.write(sr.data(), size);

    if (fill_size > 0 && left == true)
        osfill(os, fill_size, os.fill());

    return os;
}