简体   繁体   English

如何使用std:out setfill std :: setw std:right来设置一个填充空格

[英]How to format text using std:out setfill std::setw std:right with one padding space

I just want to format a string and an integer value with right justify. 我只想用右对齐格式化字符串和整数值。 There is no problem to do this without leading space before the integer value. 如果没有在整数值之前引出空格,则没有问题。

bytes.....................123981
total bytes..............1030131 

But it should look like this: 但它应该是这样的:

bytes ................... 123981
total bytes ............ 1030131

Unfortunately the example below wont work, because setw (right justify) relates only to the next stream element. 不幸的是,下面的例子不起作用,因为setw (右对齐)仅涉及下一个流元素。

int iBytes = 123981;
int iTotalBytes = 1030131;
cout << setfill('.');
cout << right;
cout << "bytes " << setw(20) << " " << iBytes << endl;
cout << "total bytes " << setw(14) << " " << iTotalBytes << endl;

I hardly ever use std::cout, so is there a simple way to do this without previously joining a space char to the value? 我几乎没有使用过std :: cout,所以有没有一种简单的方法可以在没有事先将空格char加入值的情况下执行此操作?

The simplest way would be to write your " " and value into a std::stringstream and write the resulting str() into your output stream like: 最简单的方法是将你的“”和值写入std :: stringstream并将生成的str()写入输出流,如:

std::stringstream ss;
ss << " " << iBytes;
cout << "bytes " << setw(20) << ss.str() << endl;

And here comes the complete overkill. 这就完全矫枉过正了。 A templated class prefixed which can be printed and bundles the two constructor arguments prefix,val into one string to be printed. 一个带有前缀的模板类,可以打印并将两个构造函数参数prefix,val绑定到一个要打印的字符串中。 number format, and precision is taken from the final output stream. 数字格式,精度取自最终输出流。 Works with ints,floats, strings and const char *. 使用整数,浮点数,字符串和常量字符*。 And should work with every arg that has a valid output operator. 并且应该与每个具有有效输出运算符的arg一起使用。

#include <fstream> 
#include <iostream> 
#include <iomanip> 
#include <sstream> 

using  namespace std; 

template<class T> 
class prefixed_base  { 
public: 
    prefixed_base(const std::string & prefix,const T val) : _p(prefix),_t(val) { 
    } 
protected: 
    std::string _p; 
    T           _t; 
}; 

// Specialization for const char *
template<> 
class prefixed_base<const char*>  { 
public: 
    prefixed_base(const std::string & prefix,const char * val) : _p(prefix),_t(val) { 
    } 
protected: 
    std::string _p; 
    std::string _t; 
}; 

template<class T> 
class prefixed : public  prefixed_base<T> { 
private: 
    typedef prefixed_base<T> super; 
public: 
    prefixed(const std::string & prefix,const T val) : super(prefix,val) { 
    } 

    // Output the prefixed value to an ostream
    // Write into a stringstream and copy most of the
    // formats from os.

    std::ostream & operator()(std::ostream & os) const { 
        std::stringstream ss; 

        // We 'inherit' all formats from the 
        // target stream except with. This Way we 
        // keep informations like hex,dec,fixed,precision 

        ss.copyfmt(os); 
        ss << std::setw(0); 
        ss << super::_p; 

        ss.copyfmt(os); 
        ss << std::setw(0); 
        ss << super::_t; 

        return os << ss.str(); 
    } 
}; 

// Output operator for class prefixed
template<class T> 
std::ostream & operator<<(std::ostream & os,const prefixed<T> & p) { 
    return p(os); 
} 

// This function can be used directly for output like os << with_prefix(" ",33.3)
template<class T> 
prefixed<T>    with_prefix(const std::string & p,const T  v) { 
    return prefixed<T>(p,v); 
} 

int main() { 
    int iBytes = 123981; 
    int iTotalBytes = 1030131; 
    cout << setfill('.'); 
    cout << right; 

    cout << "bytes " << setw(20) << with_prefix(" ",iBytes) << endl; 
    cout << "total bytes " << setw(14) << with_prefix(" ",iTotalBytes) << endl; 

    cout << "bla#1 "       << setw(20) <<  std::fixed << std::setprecision(9) << with_prefix(" ",220.55)      << endl; 
    cout << "blablabla#2 " << setw(14) <<  std::hex << with_prefix(" ",iTotalBytes) << endl; 
} 

@Oncaphillis thx for the piece of source code, I adapt it a bit for my needs. @Oncaphillis thx这段源代码,我根据自己的需要调整了一下。 I just wrote a function to convert values. 我刚刚编写了一个转换值的函数。 std::to_string is used by C++11 standard, so I decided to use _to_string/_to_wstring instead. std :: to_string由C ++ 11标准使用,所以我决定使用_to_string / _to_wstring。 The tricky part was to get "wcout" to work with UNICODEs on Windows console. 棘手的部分是让“wcout”与Windows控制台上的UNICODE一起工作。 I didn't really manage it, so I had to do a workaround. 我没有真正管理它,所以我不得不做一个解决方法。 Anyway to print eg Cyrillic characters you have to change the console font to Consolas or Lucida . 无论如何打印例如西里尔字符你必须将控制台字体更改为ConsolasLucida

#include <windows.h>
#include <tchar.h>
#include <iostream>
#include <iomanip>
#include <sstream>

using namespace std;

#if defined(UNICODE) || defined(_UNICODE)

    #define _tcout std::wcout
    #define _to_tstring _to_wstring

    template <typename T>std::wstring _to_wstring(const T& value) {
        std::wostringstream wos;
        wos.copyfmt(std::wcout);
        wos << value;
        return wos.str();
    }
#else
    #define _tcout std::cout
    #define _to_tstring _to_string

    template <typename T> std::string _to_string(const T& value) {
        std::ostringstream os;
        os.copyfmt(std::cout);
        os << value;
        return os.str();
    }
#endif

int _tmain(int argc, _TCHAR* argv[]) {
    int iBytes = 123981; 
    int iTotalBytes = 1030131; 

#if defined(UNICODE) || defined(_UNICODE)
    wostringstream  newCoutBuffer;
    wstreambuf*     oldCoutBuffer = _tcout.rdbuf(newCoutBuffer.rdbuf()); // redirect cout buffer
#endif

    _tcout.imbue(std::locale("German"));  // enable thousand separator
    _tcout.precision(0);
    _tcout << setfill(_T('.')) << right << fixed;

    _tcout << _T("bytes ")          << setw(20) << _T(" ") + _to_tstring(iBytes) << endl;
    _tcout << _T("bytes total ")    << setw(14) << _T(" ") + _to_tstring(iTotalBytes) << endl;
    _tcout << _T("bla bla ")        << fixed << setprecision(9); _tcout << setw(18) << _T(" ") +  _to_tstring(0.1337) << endl; 
    _tcout << _T("Милые женщины ")  << hex; _tcout << setw(12) << _T(" ") +  _to_tstring(iTotalBytes) << endl; 
    _tcout << _T("retries ")        << dec; _tcout << setw(18) << _T(" ") + _to_tstring(2) + _T(" of ") +  _to_tstring(20) << endl; 

#if defined(UNICODE) || defined(_UNICODE)
    DWORD dwWritten;
    WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), newCoutBuffer.str().c_str(),newCoutBuffer.tellp(),&dwWritten,NULL);
    _tcout.rdbuf(oldCoutBuffer);
#endif

    return 0;
}

Output: 输出:

bytes ............ 123.981
bytes total .... 1.030.131
bla bla ...... 0,133700000
Милые женщины ..... fb.7f3
retries .......... 2 of 20

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM