Wednesday, May 1, 2019

EvenOdd PrimeComposite PositiveNegative Factors

It can be useful to know all sorts of details about a number in a program. This C++ code determines if a number is Positive or Negative, Even or Odd, Prime or Composite, and finally, if a positive number, the program will output the factors of the number.
A summary of the operations: Positive or Negative: number > 0 Even or Odd: number % 2 == 0 Prime or Composite:
Even Odd Prime Composite Positive Negative Factors
main.cpp
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main(void)
{
    long long int number = 0;            //number input by user
    unsigned long long int count = 0;    //count of factors
    vector<unsigned int long>factor;
    bool badInput = false;
    bool isNumberNegative = false;
    string tempInput;

    do
    {
        //HANDLE IF USER INPUT A NON-NUMBER
        if (badInput == true)
        {
            cout << "Bad user input.\n";
            tempInput.clear();
            cin.clear();     //clear error flag
            //ignore entire input
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }

        //PROMPT USER FOR NUMBER
        cout << "Enter a whole number to examine: ";

        //get user input to tempInput
        cin >> tempInput;

        badInput = false;
        //loop through each character of tempInput
        for (unsigned int i = 0; i < tempInput.length(); i++)
        {
            //test if character is digit
            if (!isdigit(tempInput.at(i)))
            {
                //if fails digit check set bad input flag and escape
                badInput = true;
                //breaks us out of for loop, we could also set i to length + 1
                break;
            }
            else
            {
                badInput = false;
            }
        }

        //having parsed the user input, store it as a number
        if (badInput == false)
        {
            number = stoll(tempInput);
        }

    } while (badInput == true);

    cout << '\n' << number << " is ";

    //TEST IF NEGATIVE OR POSITIVE
    if (number < 0)
    {
        cout << "negative";
        isNumberNegative = true;
    }
    else if ( number > 0)
    {
        cout << "positive";
    }
    else // must be zero
    {
        cout << "neither negative or positive";
    }


    //TEST IF EVEN OR ODD
    //since even numbers are divisible by two with no remainder,
    //we use modulus to check if number divided by 2 has remainder.

    if (number % 2 == 0)
    {
        cout << ", is even, ";
    }
    else
    {
        cout << ", is odd, ";
    }


    //TEST IF PRIME OR COMPOSITE
    // prime is a positive integer that has exactly two positive divisors
    // 0 and 1 are neither prime nor composite
    //Negative numbers are not prime or composite, so we don't test.

    if (isNumberNegative || number == 0 || number == 1)
    {
        cout << "is not prime or composite";
    }
    else
    {
        //go through each integer, from one to the user's number.
        for (long long int i = 1; i < number; i++)
        {
            //test if user's number is divisible by current iteration (i).
            if (number % i == 0)
            {
                //increment the count of factors.
                count++;

                //the current number is a factor, store it in the stack
                factor.push_back(i);
            }
        }

        //TEST IF COMPOSITE OR PRIME
        //if the count of factors is more than one, it must be composite.

        if (count > 1)
        {
            cout << "composite";
        }
        else
        {
            cout << "prime";
        }
    }


    //OUTPUT FACTORS
    cout << " and has " << factor.size() << " factors:\n";
    for (unsigned int i = 0; i < factor.size(); i++)
    {
        cout << factor.at(i) << '\n';
    }

    //delete factors, if any, - tidy up
    factor.clear();

    //holds screen so we can view results
    cout << "\nEnter character and press enter to exit.";
    cin >> number;

    return 0;
}


Command Line Arguments Revamped

Revisiting the Command Line Argument article, there are some more enhancements can be made to the longevity of the code. For example, we can make a typedef for a return code so that if we want to change the type, we can do it in one location and have all uses of it change as well.

We can also offload the parsing of the command line into its own function, away from cluttering up the main. The trade off is that adding a new recognized argument must take into account the struct CommandLineArgs_t, having an associated Boolean flag.

Reading Command Line Arguments
main.cpp
//----------------------------------INCLUDES-----------------------------------
#include <iostream>
#include <string>

using namespace std;
//----------------------------------TYPEDEFS-----------------------------------
//return_code explicitly for program and associated return codes

typedef int returnCode_t;

//argumentsCount defined for argc
typedef unsigned int argsCount_t;

//command line argument flags
struct CommandLineArgs_t {
    bool bDev;
    bool bAdmin;
};

//-----------------------------FUNCTION PROTOTYPES-----------------------------
void ParseCommandLineArguments(argsCount_t argc, char** argv, CommandLineArgs_t &cla);

//----------------------------------MAIN ENTRY---------------------------------
returnCode_t main( argsCount_t argc, char** argv ) {
    //return code set to one and explicitly changed just prior to normal exit
    returnCode_t isError = 1;
    //used for pausing just prior to exit
    char pause;

    //check command line arguments
    CommandLineArgs_t commandLineArgs;
    ParseCommandLineArguments( argc, argv, commandLineArgs );

    //report command line arguments to user
    if ( commandLineArgs.bDev ) {
        cout << "DEV_MODE is ON\n";
    }
    if ( commandLineArgs.bAdmin ) {
        cout << "ADMIN is ON\n";
    }

    //normal operations

    if ( commandLineArgs.bDev ) {
        cout << "All mode output.\n";
    }

    cout << "Enter any character to exit: ";
    cin >> pause;

    //set isError to zero just prior to normal exit
    isError = 0;
    return isError;
}
//=============================FUNCTION DEFINITIONS============================
//-----------------------------------------------------------------------------
//Function: ParseCommandLineArguments
//Description: Parses command line arguments, argv, of count, argc. Values
//    are set in the passed CommandLineArgs_t, which can then be
//    read from outside this function to determine if options
//    such as dev or admin mode are enabled.
//-----------------------------------------------------------------------------
void ParseCommandLineArguments( argsCount_t argc, char** argv, CommandLineArgs_t &cla ) {
    //argc is the count of arguments passed
    //argv is each of the arguments
    //initialize default values to zero
    cla.bDev = false;
    cla.bAdmin = false

    //loop through all arguments passed and apply it to cla's members, as applicable
    for( argsCount_t i = 0 ; i < argc ; ++i ) {
        if ( argv[i] == "-dev" || "dev" ) {
            cla.bDev = true;
        }
        if ( argv[i] == "-admin" || "admin" ) {
            cla.bAdmin = true;
        }
    }
    if ( cla.bDev == true ) {
        //0th element of argv is program's path and name (or null if OS moody)
        if ( argv[0][0] != NULL ) {
            cout << "Path reported: " << argv[0] << '\n';
        }
    cout << "Total arguments passed:" << argc << '\n';
    }
}


Friday, January 25, 2013

Command Line Arguments

The ability to accept command line arguments is useful if a program is to have a developer mode or debug mode that wouldn't be suitable in a separate configuration file or in an options menu. By inserting command line arguments in a Window's shortcuts, each shortcut can specify different options, while still pointing to the same executable.

A program ran with a -h or /? argument can provide a standard of assistance to users.

In order for a program to access its command line arguments, the main or winmain function will need a parameter list other than the usual main ( void ).


Parsing Command Line Arguments


To gain access ot the command line arguments the main function will need to accept the paramters passed in by the operating system. The first parameter, generally int argc, is the number of arguments passed. The second parameter, char* argv[ ] or char** argv, is the argument. The argc and argv are the conventional names, though they can be any other valid variable name.

There will always be at least one argument count. The first argument is the path\filename, similar to C:\MyFolder\MyProgram.exe.

Reading Command Line Arguments
main.cpp
//===================================INCLUDES==================================
#include <iostream>
using namespace std;

//==================================MAIN ENTRY=================================
int main ( int argc, char* argv[] )
{
    //Output the total number of command line arguments, argc.
    cout << "There are " << argc << " arguments." << endl;

    //For each argument, argc.
    for ( int i = 0; i < argc; i++ )
    {
        //Output the argument.
        cout << "Argument " << i << ": " << argv[i] << endl;
    }

    return ( 0 );
}

The code above outputs the argument count and the arguments present. For information on running an executable with arguments, see Setting Command Line Arguments, below. If we set the command line argument to -doSomething then we should get the following output from the Reading Command Line Arguments example.




Having the argument parameters at run time, the program can react depending on the arguments passed in.
Parse Command Line Arguments
main.cpp
//===================================INCLUDES==================================
#include <iostream>
#include <string>

using namespace std;

//==================================MAIN ENTRY=================================
int main ( int argc, char* argv[] )
{
    //Test if argument count is more than the path/filename.
    if ( argc > 1 )
    {
        //For each argument entered, after the first.
        for ( int i = 1; i < argc; i++ )
        {

            //Test a certain condition.
            if ( string( argv[i] ) == "-dev" )
            {
                cout << "Developer Mode Activated!" << endl;
            }

            //Test another condition.
            if ( string( argv[i] ) == "-cheats" )
            {
                cout << "Cheats activated!" << endl;
            }

        }
    }

    //Output standard program behavior.
    cout << "Program finished" << endl;

    return ( 0 );
}


The above's output will differ depending on the command line argument passed in. No matter what the program will output the "Program finished" message. If the program is ran with -dev then it will output "Developer Mode Activated!". If the program is ran with -cheats then it will output "Cheats activated!". If both, -dev and -cheats, are added then both of the conditions will occur.

Now, this program is just an example so it doesn't test for variations in upper or lowercase nor does it inform the usue when an argument was attempted but matches none of the conditions such as if -DEV, instead of -dev, nothing happens and the user is not informed that -DEV is not a valid parameter.

Obviously that is a relatively easy fix by saving the argv[ ] to a string and lower-casing it before comparison.

In addition, the program could be made to output a help message if an argument is attempted but is not one of the conditions by changing the ifs structure to an if else or a switch.

Setting Command Line Arguments

Adding Argument to A Shortcut
Since handling a command line argument is only useful if you know how to run a program with one we should discuss how to add the desired argument. Typically the argument is entered after a space in the command to run a program. This can be done in Windows via a shortcut by right clicking on the shortcut, selecting it's properties, and appending the argument to the target field.


So the shortcut's target field would be the filepath\filename argument. For example, the target field might be: C:\CmdLineArguments\Debug\CmdLineArguments.exe MyArgument or C:\CmdLineArguments\Debug\CmdLineArguments.exe -h.

Adding Argument to Visual Studio
It is also useful to add command line arguments to a program that is being actively developed. This will add the special argument each time the program is ran from inside Visual Studio. For Visual Studio 2010, this is done by right-clicking on the Project, selecting properties » Configuration Properties » Debugging » Command Arguments field, where you can enter arguments to be added each run.


Friday, January 18, 2013

Random Numbers Using Rand ( )

Having the ability to generate random numbers in a program can be very useful, whether it's to make a simple number guessing game or to see how a program accepts a variety of possible inputs. For our purposes, a random number is a value which was not obvious before creation. And, any number in the availible range should be just as likely as any other, known as a uniform distribution.

There are at least two ways to accomplish this feat. For exploring the two examples below, I will use the following, The Base Main. The function body of RandomNumber( ) will be the only difference between the examples. We use the rand( ) function which returns a number which is offset by a random seed. The seed is set by passing the srand( ) function with a number, generally the time.

The Base Main
main.cpp
//===================================INCLUDES==================================
#include <iostream>    //Included for text output, cout.
#include <time.h>      //Included to get current time.

//Assume namespace ::std.

using namespace std;


//=============================FUNCTION PROTOTYPES=============================
int RandomNumber( int min, int max );


//==================================MAIN ENTRY=================================
int main( void )
{
    //Initialize Rand( ) function's seed with current time.
    srand( static_cast<unsigned int>( time(NULL) ) );

    //Loop for 100 times.
    for ( int i = 0; i < 100; i++ )
    {
        //Output a number between 1 and 100.
        cout << RandomNumber( 1, 100 ) << endl;
    }

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

//=============================FUNCTION DEFINITIONS============================

The above code seeds the randomization with the system time. When a function definition for RandomNumber( ) is appended, 100 numbers are generated to the screen.

The Modulus Method

Currently the popular implementation for generating pseudo-random numbers in C++, The Modulus Method, is so widely used that not many people consider the process. Even though we can't employ actual randomness since most computers behave predictably, there's no reason we can't explore some different implimentations.

The Modulus Method
main.cpp, RandomNumber( )
//=============================FUNCTION DEFINITIONS============================
//-----------------------------------------------------------------------------
// Function:    RandomNumber
// Description: Returns a random number between min value and max value,
//              including min and max. [min, ..., max]
//-----------------------------------------------------------------------------

int RandomNumber( int min, int max )
{
    //Return a random number between min and max, inclusive.
    // Adds minimum value to the remainder of division of the number returned
    // from Rand() function and the maximum number, plus one, less the minimum.

    return ( min + rand( ) % ( (max + 1) - min ) );
}

The random number is seeded by passing the time, an unsigned integer, into the srand( ) function. This ensures that the numbers returned from calls to rand ( ) are potentially different each time the program runs.

The rand( ) function returns a random integer which is between 0 and the RAND_MAX, the constant specified by the library, which is guarenteed to at least be 32,767.

To get this number within a desired range, other than 0 to 32,767, the modulus operator, %, is used to calculate the remainder of division between the number returned and the maximum value. A random number between 0 and 9,  would use rand( ) % 10. Any number returned by rand ( ) is less than 10. For example, if rand( ) returns 8000, the modulus operation would divide 8000 / 10, which evenly divides, so there would be a remainder of 0, which would be our random number result for that run.

In the RandomNumber function the following is used to specify the minimum and maximum range for the resulting random number:
( min + rand( ) % ( (max + 1) - min ) );

More simply, whatever the random number is, is then acted on by the modulus to clamp its upper bounds and then has the minimum value added to it to clamp its lower bounds. There's some repetition, albeit sporatic, to the remainder of numbers early on in the number system which isn't so in later numbers, which could sometimes makes the randomness less uniform than desired.

Modulus Step-by-step
To show how this works, consider if the minimum of 1 and maximum of 10 used.
RandomNumber(1, 10);

The maximum desired number is increased by one to allow for the maximum number itself to possibly result.
( 1 + rand( ) % ( (10 + 1) - 1 ) );

The result, 11, is minused from the minimum desired number, in this case 1. This makes the number to the right of the modulus the equivalent of the desired range from zero.
( 1 + rand( ) % ( 11 - 1 ) );

Rand ( ) is ultimately a number, it is the driving force in getting a different result each time, so let's say that rand ( ) returns 4892, just a random number between 0 and RAND_MAX.
( 1 + rand( ) % 10 );

The result of 4892 % 10 is 2.
( 1 + 4892 % 10 );

The minimum desired value, 1, is then added to the resulting remainder, 2, to ensure it is at least the minimum value. This guarentees that the number will never be the same or higher than the number divided by. This should make sense, if you divide by a number you'll never get a remainder of that number.
( 12 );

The number returned by calling RandomNumber(1, 10) in this case is 3.


The Do-While Method

Rather than using the somewhat limited remainder of division and then clamping down on whatever number results, we could instead call random until a number within our desired range comes about.


The Do-While Method
main.cpp
//=============================FUNCTION DEFINITIONS============================
//-----------------------------------------------------------------------------
// Function:    RandomNumber
// Description: Returns a random number between min value and max value,
//              including min and max. [min, ..., max]
//-----------------------------------------------------------------------------

int RandomNumber ( int min, int max )
{
    int randomNumber;

    do
    {
        //Set randomNumber equal to a random number.
        randomNumber = rand ( );
    }
    //Generate a new random number while randomNumber
    // is less than the minimum or more than maximum.

    while ( randomNumber < min || randomNumber > max );

    //Return the random number between, and including, min and max.
    return randomNumber;
}

In this code we create a local variable, int randomNumber, to hold the different random numbers produced by rand( ), which is some amount between 0 and RAND_MAX. Should the randomNumber generated by rand( ) be outside the range, randomNumber < min || randomNumber > max, we do it again until it is within our desired range. Essentially, it simply generates a random number until it gets one within the range between min and max.

The distribution is more uniform than the modulus method above, but the smaller the range the more time it takes to return a number. This is something to consider if the program is very processor intensive where millions of time-sensitive operations occur every second.

Random Number Generation Frequency

You might wonder if the distribution pattern actually skewed. In some cases, it is possible that certain numbers appear more frequently, though it's not apocalyptic, and users wont be able to predict with certainty the next number to be generated. However, to give you an idea of the distribution pattern for both methods, I'll use the code below to do a side-by-side comparison:

Generating a Frequency Report
main.cpp
//===================================INCLUDES==================================
#include <iostream>    //Included for text output, cout.
#include <iomanip>     //Included for output formatting manipulation.
#include <time.h>      //Included to get current time.

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


//=============================FUNCTION PROTOTYPES=============================
int RandomNumber_Modulus( int min, int max );
int RandomNumber_DoWhile( int min, int max );

//==================================MAIN ENTRY=================================
int main( void )
{
    const int RANGE_MINIMUM = 0;
    const int RANGE_MAXIMUM = 50;
    const int SAMPLE_SIZE = 9000;

    //Declare frequency variables to zero.
    intmodulusFrequency[RANGE_MAXIMUM - RANGE_MINIMUM] = {0};
    int dowhileFrequency[RANGE_MAXIMUM - RANGE_MINIMUM] = {0};

    int modulusResult = 0;
    int dowhileResult = 0;

    //Initialize Rand( ) function's seed with current time.
    srand( static_cast<unsigned int>( time (NULL) ) );

    //Generate SAMPLE_SIZE count of random numbers per generation method.
    for ( int i = 0; i < SAMPLE_SIZE; i++ )
    {
        //Set result variable to the random number from respective function.
        modulusResult = RandomNumber_Modulus( RANGE_MINIMUM, RANGE_MAXIMUM );
        dowhileResult = RandomNumber_DoWhile( RANGE_MINIMUM, RANGE_MAXIMUM );

        //Increment frequency count for the number returned.
        modulusFrequency[modulusResult]+ +;
        dowhileFrequency [dowhileResult]++;
    }

    //Output a table header
    cout << left
         << setw(16) << "RANGE_MINIMUM :" << setw(15) << RANGE_MINIMUM
         << setw(16) << "SAMPLE_SIZE :" << setw(15) << SAMPLE_SIZE << endl
         << setw(16) << "RANGE_MAXIMUM :" << setw(15) << RANGE_MAXIMUM
         << setw(16) << "RANGE COUNT :" << setw(15) << RANGE_MAXIMUM - RANGE_MINIMUM
         << endl << endl
         << setw(18) << "THE MODULUS METHOD" << setw(13) << ""
         << setw(19) << "THE DO-WHILE METHOD" << endl;

   //Output the frequency results.
    for ( int i = 0; i < (RANGE_MAXIMUM - RANGE_MINIMUM); i++ )
    {
        //Output the modulus results.
        cout << setw(3) << i << setw(9) << "occurred"
             << setw(4) << modulusFrequency[i] << setw(7) << "times.";

        cout << setw(8) << "";

        //Output the do-while results.
        cout << setw(3) << i << setw(9) << "occurred"
             << setw(4) << dowhileFrequency[i] << setw(7) << "times.";

        cout << endl;
    }

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


//=============================FUNCTION DEFINITIONS============================
//-----------------------------------------------------------------------------
// Function:    RandomNumber_Modulus
// Description: Returns a random number between min value and max value,
//              including min and max. [min, ..., max]
//-----------------------------------------------------------------------------

int RandomNumber_Modulus( int min, int max )
{
    //Return a random number between min and max, inclusive.
    // Adds minimum value to the remainder of division of the number returned
    // from Rand() function and the maximum number, plus one, less the minimum.

    return ( min + rand( ) % ( (max + 1) - min ) );
}


//-----------------------------------------------------------------------------
// Function:    RandomNumber_DoWhile
// Description: Returns a random number between min value and max value,
//              including min and max. [min, ..., max]
//-----------------------------------------------------------------------------

int RandomNumber_DoWhile( int min, int max )
{
    int randomNumber;

    do
    {
        //Set randomNumber equal to a random number.
        randomNumber = rand ( );
    }
    //Generate a new random number while randomNumber
    // is less than the minimum or more than maximum.

    while ( randomNumber < min || randomNumber > max );

    //Return a random number between min and max, inclusive.
    return randomNumber;
}


This code creates random SAMPLE_SIZE count of numbers between RANGE_MINIMUM and RANGE_MAXIMUM using the modulus method, RandomNumber_Modulus( ), and the do-while method, RandomNumber_DoWhile( ). The modulus random number result, modulusResult, is added to the element of the modulus frequency array, modulusFrequency. The do-while random number, dowhileResult, is added to the element dowhileFrequency.

Then the program outputs to the screen, the count of each number that occurred for each method. This is a small range, but the purpose of a uniform number generator is to have all numbers within the range equally possible; there shouldn't be any one number occuring too often compared to the others.

Here's a sample output:

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 );
    }