使用C ++中的流操纵器将定宽字段中的文本居中 [英] Center text in fixed-width field with stream manipulators in C++

查看:108
本文介绍了使用C ++中的流操纵器将定宽字段中的文本居中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在重构一些使用printf并带有long字符串(没有任何实际格式)的旧代码,以打印出纯文本表头,看起来像这样:

I am refactoring some legacy code which is using printf with longs strings (without any actual formatting) to print out plain text table headers which looks notionally like this:

|  Table   |  Column  | Header  |

目前正在以这种方式生产:

which are currently being produced like this:

printf("|  Table   |  Column  | Header  |");

我想用 1 效果的代码生成以上代码:

I would like to produce the above with code to the effect of1:

outputStream << "|" << std::setw(10) << std::center << "Table"
             << "|" << std::setw(10) << std::center << "Column"
             << "|" << std::setw(9) << std::center << "Header"
             << "|" << std::endl;

因为<iomanip>具有流操纵器std::leftstd::rightstd::internal而未编译的

,但似乎没有任何std::center.在标准C ++库中是否已经有一种干净的方法可以做到这一点,还是我必须手动计算必要的间距?

which does not compile because <iomanip> has the stream manipulators std::left, std::right and std::internal, but does not seem to have any std::center. Is there a clean way to do this already in standard C++ libraries, or will I have to manually compute the necessary spacing?

1 尽管这比C代码更冗长,但从长远来看,由于printf语句的数量和ins中重复插入量的增加,它的冗长程度也较小.他们的弦.它将更加可扩展和可维护.

1Even though this is more verbose than the C code, it will be less verbose in the long run because of the number of printf statements and the amount of infixed duplication in their strings. It will also be more extensible and maintainable.

推荐答案

以下是完成您想要的工作的帮助程序类:

Here's a helper class that accomplish what you want:

#include <string>
#include <iostream>
#include <iomanip>

template<typename charT, typename traits = std::char_traits<charT> >
class center_helper {
    std::basic_string<charT, traits> str_;
public:
    center_helper(std::basic_string<charT, traits> str) : str_(str) {}
    template<typename a, typename b>
    friend std::basic_ostream<a, b>& operator<<(std::basic_ostream<a, b>& s, const center_helper<a, b>& c);
};

template<typename charT, typename traits = std::char_traits<charT> >
center_helper<charT, traits> centered(std::basic_string<charT, traits> str) {
    return center_helper<charT, traits>(str);
}

// redeclare for std::string directly so we can support anything that implicitly converts to std::string
center_helper<std::string::value_type, std::string::traits_type> centered(const std::string& str) {
    return center_helper<std::string::value_type, std::string::traits_type>(str);
}

template<typename charT, typename traits>
std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& s, const center_helper<charT, traits>& c) {
    std::streamsize w = s.width();
    if (w > c.str_.length()) {
        std::streamsize left = (w + c.str_.length()) / 2;
        s.width(left);
        s << c.str_;
        s.width(w - left);
        s << "";
    } else {
        s << c.str_;
    }
    return s;
}

只需调用centered("String")就可以使用它,就像这样:

It's used simply by calling centered("String"), like so:

int main(int argc, char *argv[]) {
    std::cout << "|" << std::setw(10) << centered("Table")
              << "|" << std::setw(10) << centered("Column")
              << "|" << std::setw(9)  << centered("Header") << "|"
              << std::endl;
}

这篇关于使用C ++中的流操纵器将定宽字段中的文本居中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆