代码之家  ›  专栏  ›  技术社区  ›  Nick

如何将以非空结尾的字符串输出到iostream,但保持格式

  •  0
  • Nick  · 技术社区  · 7 年前

    我试图输出非空的终止字符串,但保留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() );
    }
    

    这在linux和gcc上可以正常工作,但在macos和clang上失败。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Nick    7 年前

    关于 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;
    }