Centering output issue

Jun 1, 2014 at 1:25am
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;
Jun 1, 2014 at 2:25am
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
Jun 1, 2014 at 4:20am
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-----]
Jun 1, 2014 at 6:02am
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 Jun 1, 2014 at 6:11am
Jun 1, 2014 at 9:14am
Which one would be more efficient in the compiling and loading processes?
Jun 1, 2014 at 2:13pm
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.
Jun 1, 2014 at 3:57pm
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?
Jun 1, 2014 at 5:27pm
> 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.