Centering output issue

Hi everyone,

I have a little issue I'll like to ask here. How do I align all the output to approximately the center (just not aligned totally to the left.) and then all the content would be neatly aligned. How do you make the output be like this:

[-----------TEXT HERE---------------]
[-----------BIGGER TEXT HERE-----]

Would this be a good practice?
1
2
3
4
cout<<setw(10)<<""<<"CONTENT";
cout<<endl;
cout<<setw(10)<<""<<"CONTENT";
cout<<endl;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>

struct centre
{
    template < typename T > centre( unsigned int width, const T& v ) : width(width) { put(v) ; }

    template < typename... T > centre( unsigned int width, const T&... v ) : width(width) { put(v...) ; }

    template < typename T > void put( const T& v ) { stm << v ; }

    template < typename FIRST, typename... REST >
    void put( const FIRST& first, const REST&... rest ) { stm << first ; put(rest...) ; }

    std::string value() const
    {
        std::string result = stm.str() ;

        if( width > result.size() )
        {
            auto n = width - result.size() ;
            if( n > 1 ) result = std::string( n/2, ' ' ) + result ;
            result += std::string( (n+1) / 2, ' ' ) ;
        }

        return result ;
    }

    const unsigned int width ;
    std::ostringstream stm ;
};

std::ostream& operator<< ( std::ostream& stm, const centre& c ) { return stm << c.value() ; }

int main()
{
    std::cout << '|' << centre( 40, "hello world" ) << "|\n"
              << '|' << centre( 40, "first value: ", std::fixed, std::setprecision(2), 6.7 ) << "|\n"
              << '|' << centre( 40, "the second value is: ", std::setw(6), std::internal, std::setfill('0'), -123 ) << "|\n" ;
}

http://coliru.stacked-crooked.com/a/ce3951ce6409ada1
But this only centers everything.

I don't want the output to be like :

[---------------TEXT HERE---------------]
[----------BIGGER TEXT HERE----------]

I want it to be like:

[-----------TEXT HERE---------------]
[-----------BIGGER TEXT HERE-----]
For that, what you did in the first post is fine.

If we want to get cute:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <iomanip>

struct space
{
    constexpr space( int n ) : value(n) {}
    const int value ;
};

std::ostream& operator<< ( std::ostream& stm, space s )
{ return stm << std::setw(s.value) << ' ' ; }

int main()
{
    std::cout << "...............\n"
              << space(15) << "hello world\n"
              << space(15) << "the value is: " << std::fixed << 6.7 << '\n' ;
}

http://coliru.stacked-crooked.com/a/702b174470f5d55e
Last edited on
Which one would be more efficient in the compiling and loading processes?
There would be no difference in performance between
std::cout << space(20) << 100 ; and std::cout << std::setw(20) << ' ' << 100 ;
if the overloaded operator<<() is inline.
But then it would be a lot of work to add:
cout<<setw()<<""

to every set of code and output. Aren't there any way to make all the outputs be like that universally?
> Aren't there any way to make all the outputs be like that universally?

This crude hack should suffice, as long as we don't flush the stream in the middle of a line:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>

struct shifted_stdout : public std::ostream
{
    explicit shifted_stdout( std::size_t shift )
        : std::ostream( &buf ), spacer( shift, ' ' ) {}

    virtual ~shifted_stdout() { flush() ; }

    shifted_stdout& flush()
    {
        std::istringstream stm( buf.str() ) ;

        std::string line ;
        while( std::getline( stm, line ) )
            std::cout << spacer << line << '\n' ;

        buf.str("") ;
        return *this ;
    }

    private:
        std::stringbuf buf ;
        const std::string spacer ;
};

int main()
{
   shifted_stdout sout(10) ;

   sout << "hello world\n"
        << "value is: " << std::setw(8) << std::internal << -12345 << std::endl
        << "the second value is: " << std::fixed << std::setprecision(2) << 6.7
        << "\nthis line is not yet complete -- " ;

   // sout.flush() ; // NO

   sout << "line is completed now.\n" ;
}

http://coliru.stacked-crooked.com/a/4bca4f663f38e4a8
Topic archived. No new replies allowed.