Showing posts with label Console Window. Show all posts
Showing posts with label Console Window. Show all posts

Friday, January 11, 2013

Dividing and Centering Text Output


Dividing and Centering Text Output


Sometimes we need text output to the console window or a file to be centered and or preceeded by a divider to make it more readable. In such cases, we can create two functions OutputDivider ( ) and OutputCentered ( ) to add to our formatting ability. A complete program example at the end shows how to use both functions together.

The OutputDivider Function:

The divider function should accept a stream to output. The stream could be a file stream, ifstream, or output to the screen, cout. We should set what character is repeated across the screen and how many times, which is the desired length of the divider.

Function Definition:
OutputDivider( )
//-----------------------------------------------------------------------------
// Function:     OutputDivider
// Description:  Output fillSymbol character a count of numberOfSymbols to
//               streamOut, keeping the original fill character when done.
//-----------------------------------------------------------------------------

void OutputDivider( ostream& outStream, char fillSymbol, int numberOfSymbols )
{
     char oldFillSymbol;

     //Set oldFillSymbol to the current fill character.
     oldFillSymbol = outStream.fill( );

     //Set the fill to the fillSymbol passed.
     outStream.fill( fillSymbol );

     //Output to stream, outStream, the fill across width, numberOfSymbols.
     outStream << setw( numberOfSymbols ) << "" << endl;

     //Restore old fill symbol so not to affect outside setw( ) formatting.
     outStream.fill( oldFillSymbol );
}

This function works by accepting, as the first parameter, an ostream which all output will be sent to, named outStream. This might be a type of file stream, such as ofstream, perhaps named myOutputFile, or to cout, the screen. The second parameter passed into the function is char fillSymbol, which is the symbol or character to be output. The third parameter, int numberOfSymbols, is the number of times the character is repeatedly printed.

Once a fill symbol is set for a stream, such as with a call to outStream.fill( ) the symbol for that stream is then changed going forward, whether or not we are in the local scope of a function or not. This is because we are directing changes to the actual stream itself, through the reference to ostream& instead of a local copy. To make sure outside calls to setw( ) aren't changed after each run of our function we store the original fill in char oldFillSymbol to be restored at the end.

Then we set the fill to fillSymbol passed and subsequently output the fill across the screen using setw( ). Here's how the function is called, see the final example at the end for further clarification:

Function Call:
OutputDivider( )
//Output to cout a divider of dashes, '-', across the screen, 50 chars.
OutputDivider ( cout, '-' , 50 );



The OutputCentered Function:

The OutputCentered ( ) function should accept a stream, similar to the OutputDivider() function above. The output will be of some text, a string, in the center of the resulting output.
Function Definition
OutputCentered( )
//-----------------------------------------------------------------------------
// Function:    OutputCentered
// Description: Outputs to output stream passed, outStream, the string of text
//              passed, centerText, across the desired number of characters,
//              screenLength.
//-----------------------------------------------------------------------------

void OutputCentered( ostream& outStream, string centerText, int screenLength )
{
     int centeredLength;

     //Minus the length of the text from the output's total length, screenWidth.
     centeredLength = screenLength - centerText.length( );

     //Test if centering is necessary, the centeredLength is two or more.
     if (centeredLength >= 2)
     {
          //Calculate total width of output to be appropriately centered.
          centeredLength = ( (centeredLength / 2) + centerText.length( ) );
     }

     //Output centerText, string passed, across centeredLength.
     outStream << setw( centeredLength ) << centerText << endl;
}


This function works by accepting, as the first parameter, an ostream which all output will be sent to, named outStream. Again, this might be a type of file stream, such as an ofstream or just an output to screen, cout. The second and third parameter, a string centerText and then int screenLength which specifies the length of characters to center the text across.

To understand how this works consider screenLength value represents the number of boxes lined up in a row. We need to put the characters of string centerText in the center-most boxes. In order to know which box is destined to be an empty box, or how many boxes to keep empty as we move from left to right we start by finding out how many empty boxes we'll actually have. To do that we minus the length of the text from the total screen size. The second line of the function does this exactly, determines the number of empty boxes (characters).

Next, we test if we need to center at all. If we know there are two or more empty boxes than there are characters the we should do some centering, otherwise there will be no even number of empty boxes so there's no centering possible and the function should just output string centerText.

If there is centering to be done we calculate the length to center across, dividing the number of empty characters, centeredWidth and adding in the length of the string.

Finally, the function outputs the centerText, which is centered using setw( ) to set the width/length of the calculated centeredLength.

Function Call:
OutputCentered( )
//Output the text, "Centered!", to cout centered across fifty characters.
OutputCentered ( cout, "Centered!", 50 );


The Complete Example

To wrap up, we can observe both the OutputCentered and Output functions working side by side to  tidy up output.


Complete Example, using OutputCentered and OutputDivider
main.cpp
//===================================INCLUDES==================================
#include <iostream> //Included for text output, cout.
#include <iomanip> //Included for setw(), fill(), output manipulation.
#include <string> //Included for string type.

//Assuming namespace ::std.
using namespace std;

//=============================FUNCTION PROTOTYPES=============================
void OutputDivider( ostream& outStream, char fillSymbol, int numberOfSymbols );
void OutputCentered( ostream& outStream, string centerText, int screenLength );

//==================================MAIN ENTRY=================================
int main( void )
{
    //The length of the output, used to set all lengths the same.
    int outputLength = 60;

    //A string to output, centered, at some point.
    string str1 = "Neato, n Stuff";


    //Output a divider of outputLength number of characters.
    OutputDivider ( cout, '=', outputLength );

    //Output "Centered!" centered across outputLength number of characters.
    OutputCentered ( cout, "Centered!", outputLength );

    //Output a divider of outputLength number of characters.
    OutputDivider ( cout, '*', outputLength );

    //Output the string, str1, centered on the screen.
    OutputCentered ( cout, str1, outputLength );


    //End the program, returning zero.
    return ( 0 );
}


//=============================FUNCTION DEFINITIONS============================
//-----------------------------------------------------------------------------
// Function:     OutputDivider
// Description:  Output fillSymbol character a count of numberOfSymbols to
//               streamOut, keeping the original fill character when done.
//-----------------------------------------------------------------------------

void OutputDivider( ostream& outStream, char fillSymbol, int numberOfSymbols )
{
     char oldFillSymbol;

     //Set oldFillSymbol to the current fill character.
     oldFillSymbol = outStream.fill( );

     //Set the fill to the fillSymbol passed.
     outStream.fill( fillSymbol );

     //Output to stream, outStream, the fill across width, numberOfSymbols.

     outStream << setw( numberOfSymbols ) << "" << endl;
     //Restore old fill symbol so not to affect outside setw( ) formatting.
     outStream.fill( oldFillSymbol );
}


//-----------------------------------------------------------------------------
// Function:    OutputCentered
// Description: Outputs to output stream passed, outStream, the string of text
//              passed, centerText, across the desired number of characters,
//              screenLength.
//-----------------------------------------------------------------------------

void OutputCentered( ostream& outStream, string centerText, int screenLength )
{
     int centeredLength;

     //Minus the length of the text from the output's total length, screenWidth.
     centeredLength = screenLength - centerText.length( );

     //Test if centering is necessary, the centeredLength is two or more.
     if (centeredLength >= 2)
     {
          //Calculate total width of output to be appropriately centered.
          centeredLength = ( (centeredLength / 2) + centerText.length( ) );
     }

     //Output centerText, string passed, across centeredLength.
     outStream << setw( centeredLength ) << centerText << endl;
}


Output:

Friday, January 4, 2013

Console Window - Colored Text


Colored Text

If you've ever wanted to use colors in a console window, as in having a colorful text and backgrounds, then are two primary methods:
  • the System ( ) method
  • the SetConsoleTextAttribute ( ) method


  • The System ( ) can be used on several operating systems but doesn't allow multiple colors to appear at once. SetConsoleTextAttribute ( ) requires the <Windows.h> library is included but will allow multiple colors at once.

    Both use color codes of a hexadecimal notation, such as FF. The first digit is the background and the second is the text or foreground. For a complete color table, see the final output example.

    The System ( ) Method

    System("color F0"); which changes the color of the environment. Consider the following:

    Using the system( ) function
    main.cpp
    //===================================INCLUDES==================================
    #include <iostream>

    Assuming namespace ::std.
    using namespace std;

    //==================================MAIN ENTRY=================================
    int main ( void )
    {
        //Set the system color to 0xC1.
        system("color C1");

        //Output some text to the screen.
        cout << "This text is made colorful by the system( ) function." << endl;

        return ( 0 );
    }


    Outputs:



    SetConsoleTextAttribute ( ) Method


    The SetConsoleTextAttribute ( ) method allows for much more control over coloring text.
    Using the system( ) function
    main.cpp
    //===================================INCLUDES==================================
    #include <iostream>
    #include <Windows.h>

    Assuming namespace ::std.
    using namespace std;

    //==================================MAIN ENTRY=================================
    int main ( void )
    {
        //Handle to console window's context.
        HANDLE hConsole = GetStdHandle ( STD_OUTPUT_HANDLE );


        //Set the color (0x0E = Black Background, Yellow Foreground )
        SetConsoleTextAttribute ( hConsole, 0x0E );

        cout << "Text made colorful by SetConsoleTextAttribute( ) function." << endl;

        return ( 0 );
    }



    In-Depth SetConsoleTextAttribute ( ) Method

    In this example we'll create a function, GetColorCode ( ) and loop through all the possible colors.
    The SetConsoleTextAttribute ( ) Method
    main.cpp
    //===================================INCLUDES==================================
    #include <iostream>
    #include <iomanip>
    #include <Windows.h>

    using namespace std;


    //=============================FUNCTION PROTOTYPES=============================
    unsigned char GetColorCode ( unsigned char colorBackground,
                                 unsigned char colorForeground );


    //==================================MAIN ENTRY=================================
    int main( void )
    {
          //handle to console window's context
          HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

          unsigned char colorBackground = 0x00; //background color code
          unsigned char colorForeground = 0x00;//foreground color code
          unsigned char colorCode = 0x00; //high:background, low:foreground


          //---------------OUTPUT COLORFUL LITERAL---------------
          //set text color (0x08 = black background, grey foreground)
          SetConsoleTextAttribute ( hConsole, 0x08 );
          cout << "I don't always like ";

          //set text color (0x0E = black background, yellow foreground)
          SetConsoleTextAttribute(hConsole, 0x0E);
          cout << "Cake";

          //set text color (0x08 = black background, grey foreground)
          SetConsoleTextAttribute(hConsole, 0x08);
          cout << ", but when I do it's always a ";

          //set text color (0xC0 = red background, black foreground)
          SetConsoleTextAttribute(hConsole, 0xC0);
          cout << "Lie!" << endl << endl << endl;



          //------------------OUTPUT COLOR CHART-----------------
          //output hexidecimal notation
          cout << setbase(16);

          //loop through each background color (0 to 15 = 16 possible colors)
          for (colorBackground = 0; colorBackground < 16; colorBackground++)
          {

               //loop through each foreground color (0 to 15 = 16 possible colors)
               for (colorForeground = 0; colorForeground < 16; colorForeground++)
               {

                    //get color code as one variable
                    colorCode = GetColorCode(colorBackground, colorForeground);

                    //set front and back colors
                    SetConsoleTextAttribute(hConsole, colorCode);

                    //output the color code
                    cout << setfill('0')                 //set fill character
                         << setw(2)                      //create width for numbers
                         << uppercase                    //set output to uppercase
                         << static_cast<int>(colorCode)  //print colorCode as hex
                         << ' ';                         //padding for next value
               }

              //start new line for next background color
              cout << '\n';
          }

          return ( 0 );
    }


    //=============================FUNCTION DEFINITIONS============================
    unsigned char GetColorCode ( unsigned char colorBackground,
                                 unsigned char colorForeground )
    {
          //return most signifigant bit of colorBackground and
          //least signifigant bit of colorForground as one byte
          return (colorBackground << 4) + colorForeground;
    }

     Outputs:


    The program creates a HANDLE or a context of the console environment to affect the color code of that environment. Next we create an unsigned char for the colorBackground, the background of the text area, colorForeground, the foreground of the text itself, and colorCode, both the background and foreground combined into a single hexadecimal number.
    Since the colorCode is actually two hexidecimal digits, or places, which can never be negative we use unsigned. The reason we use char, despite the fact that the background color is only 4 bits, compared to the char being 8 bits, is because there is no smaller variable size availible (other than bool).

    We are only using four bits from each code, again, because the color code is only 8 bits, we must later take the four bits from ColorBackground (which are the left-most, or the high bits) and add in the colorForground bits.

    To make this intuitive:
    colorBackground = 1111 0000b;
    colorForeground = 0000 1111b;

    After we call GetColorCode(colorBackground, colorForeground) the colorCode would be equal to 1111 1111b.

    Friday, December 28, 2012

    Console Window - Christmas Tree


    Console Window Christmas Tree

    As a festive programming challenge, programmers are tasked with creating a Christmas Tree out of asterisks, '*', which is the ASCII character code '\xCE'. The purpose of this challenge is to use for loops and setw( ) from the <iomanip> library to create The Desired Output. As such, you cannot simply output a string of spaces and asterisks.

    The solution requires an understanding of for loops and an understanding of what is necessary mathematically. Don't let that scare you, it's not difficult math: Addition, subtraction and possibly multiplication. There are many possible ways to achieve the goal. This is a problem which requires some complex thought so don't get discouraged if it doesn't come to you right away.

    To start, let's take a look at The Desired Output.

    The Desired Output
        *
       ***
      *****
     *******
    *********



    Tackling the Tree

    First, we notice that the count of characters, number of asterisks, that are output each line starts with one character and increases by two every line after. Also, starting with the number one and adding two each time ensures that the number will always be the same, either an even or odd value, that it was originally.

    Why is it important that the number of characters being output is an odd count? It is necessary so that a single character acting as the center of the tree. If we had an even number of characters there wouldn't be one center character and the tree would not be as centered.

    Knowing that we will want to store the number of characters we are currently sending to the output we can declare an unsigned int variable, which we'll name x. We'll also want to declare a variable to hold the current line, which will hold our current line, unsigned int y.

    The number of lines, the final and desired height of the tree, which will not change throughout the program we can declare as an const unsigned int variable, HEIGHT.

    How do we know where to go from there? Well, that's tricky but we know that we're going to need a basic program setup so let's start with what we have so far:

    The Start of the Tree
    main.cpp
    //===================================INCLUDES==================================
    #include <iostream>     //Included for text output, cout.
    #include <iomanip>      //Included for setw(), fill(), output manipulation.

    //Assuming namespace ::std.

    using namespace std;


    //==================================MAIN ENTRY=================================
    int main( void )
    {
         //The desired height of the tree.
         const unsigned int HEIGHT = 5;

         //The current width of the tree.
         unsigned int x;

         //The current height of the tree.
         unsigned int y;

         //The for loop solution
         //...

         //End the program, returning zero.

         return ( 0 );
    }


    Using what we know, that the x variable depends on the y, we can assume the loop dealing with height will be the first loop which will then have a second loop that outputs the correct number of characters.

    The count of characters from left to right, will be depends on the height. We know that the height, loop dealing with the y will be the outer-most for loop and that the inner-loop, the x loop, will have a condition which is directly affected by the current line number.

    Part of a Possible Solution
    main.cpp, for loop part 1
    //Set current line, y, to 1 since we'll need it
    // to calculate number of asterisks to output, x.
    for ( y = 1; y < HEIGHT; y++ )
    {
         //Set width before the asterisk(s) to HEIGHT minus the current line, y.
         cout << setw( HEIGHT - y );

         //Consider what conditional would be appropriate.
         for ( x = 1; x < conditional ; x++ )
         {
              cout << '*';
         }

         cout << endl;
    }


    Try a few things, again -- there are many possible solutions. The following is the complete code of one solution.

    One Possible Complete Solution:


    A Completed Christmas Tree
    main.cpp

    //===================================INCLUDES==================================
    #include <iostream>     //Included for text output, cout.
    #include <iomanip>      //Included for setw(), fill(), output manipulation.

    //Assuming namespace ::std.
    using namespace std;

    //==================================MAIN ENTRY=================================
    int main( void )
    {
         //The desired height of the tree, plus one.
         const unsigned int HEIGHT = 6;

         //The current width of the tree.
         unsigned int x;

         //The current height of the tree.
         unsigned int y;


         //The for loop solution.
         //Loop through each line, up to a count of HEIGHT - 1 times.
         for ( y = 1; y < HEIGHT; y++ )
         {
              //Set width before the asterisk(s) to HEIGHT minus the current line, y.
              cout << setw( HEIGHT - y );

              //Loop until the current asterisk, x, is less than twice the line, y.
              for ( x = 1; x < y * 2; x++ )
              {
                   //Output the asterisk.
                   cout << '*';
              }

              //End the output to the current line.
              cout << endl;
         }

         //End the program, returning zero.
         return ( 0 );
    }