21

printf概念的には次のように見えるプレーンテキストのテーブルヘッダーを出力するために、(実際の書式設定なしで) long 文字列を使用しているいくつかのレガシーコードをリファクタリングしています:

|  Table   |  Column  | Header  |

現在、次のように作成されています。

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

1の効果を持つコードを使用して上記を作成したいと思います。

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

<iomanip>ストリームマニピュレータstd::leftstd::rightおよびがあるため、コンパイルされませんstd::internalが、 はないようですstd::center。標準の C++ ライブラリで既にこれを行うクリーンな方法はありますか、それとも必要な間隔を手動で計算する必要がありますか?


1これは C コードよりも冗長ですが、printfステートメントの数と文字列内の固定重複の量により、長期的にはそれほど冗長ではなくなります。また、拡張性と保守性も向上します。

4

6 に答える 6

15

これは、あなたが望むものを達成するヘルパークラスです:

#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")次のようにを呼び出すだけで使用できます。

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;
}
于 2013-02-13T19:18:55.557 に答える
7

std::centerマニピュレーターはありません。私はあなたがそれを自分でしなければならないのではないかと心配しています。作業を減らすために、幅と文字列を指定してスペースを計算するヘルパー関数を作成できます。

ヘルパー関数がどのように見えるかのサンプルを次に示します。より効率的にするためには、いくつかの作業が必要です。

string helper(int width, const string& str) {
    int len = str.length();
    if(width < len) { return str; }

    int diff = width - len;
    int pad1 = diff/2;
    int pad2 = diff - pad1;
    return string(pad1, ' ') + str + string(pad2, ' ');
}
于 2013-02-13T19:07:46.073 に答える
3

手動で行う必要があると思います。しかし、文字列を操作する場合はそれほど難しくありません。何かのようなもの:

std::string
centered( std::string const& original, int targetSize )
{
    assert( targetSize >= 0 );
    int padding = targetSize - checked_cast<int>( original.size() );
    return padding > 0
        ? std::string( padding / 2, ' ' ) 
            + original
            + std::string( targetSize - (padding / 2), ' ' )
        : original;
}

トリックを行う必要があります。

于 2013-02-13T19:10:34.170 に答える
0

NCURSESライブラリを使用できます...ちょっとファンクで、コンパイルコマンド(g ++ -L NCURSES yourProgram.cpp)に「-L NCURSES」を追加する必要があり、それが機能するだけでなく、色やその他の「クール」を実行できますスタッフ[とにかくCLIにとってクール]。マニュアルを読むだけで、センタリングはとても簡単です。 http://tldp.org/HOWTO/NCURSES-プログラミング-HOWTO/

于 2017-04-22T00:16:12.417 に答える