Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

CBuilder - An STL 'replacement' for the FormatMessage API

4.17/5 (5 votes)
27 Sep 2012CPOL3 min read 18.3K   259  
This is an alternative for MakeMessage - An STL 'replacement' for the FormatMessage API

Introduction

This article presents an alternative method to my previous 'MakeMessage' class.
The pja::CBuilder class presented in this article uses positional parameters to format text strings. The parameters can be of any type, intergral or user defined, that has a friend std::ostream& operator <<() defined as all the parameters are formatted into strings by passing them into a std::ostringstream object. These strings are then inserted into the original format string at the specified positions.

Example usage

Example 1 - a basic example

#include "builder.h"

std::string format = "The first parameter is {0}, the second is {1}.";
pja::CBuilder<> output(format, 15, 25.45);
std::cout << output << std::endl;

The result of this example is:

The first parameter is 15, the second is 25.45.

Example 2 - using different insertion markers

#include "builder.h"
typedef pja::CBuilder<'%', '#'> MyBuilder;

std::string format = "The second parameter is %1#, the first is %0#.";
MyBuilder output(format, 15, 25.45);
std::cout << output << std::endl;

The result of this example is:

The second parameter is 25.45, the first is 15.

Example 3 - using the % operator to add parameters

#include "builder.h"

std::string format = "The first parameter is {0}, the second is {1}.";
pja::CBuilder<> output(format);
output % 15;
output % 25.45;
std::cout << output << std::endl;

The result of this example is:

The first parameter is 15, the second is 25.45.

Example 4 - using a user defined modifier class

#include "builder.h"

class Hex // Hexadecimal formatted output
{
private:
    unsigned int h;
public:
    Hex(unsigned int _h) : h(_h) {}
    friend std::tostream& operator << (std::tostream &os, const Hex& me)
    {
        std::ios_base::fmtflags flags = os.flags();     // get the current format flags
        os.unsetf(std::ios::dec);                       // clear the decimal flag
        os.setf(std::ios::hex | std::ios::uppercase);   // set the hexadecimal and uppercase flags
        os.fill('0');                                   // have leading zeroes
        os.width(2);                                    // and at least two digits
        os << "0x" << me.h;                             // output the hexadecimal number
        os.setf(flags);                                 // reset the former format flags
        return os;
    }
};

pja::CBuilder<> output("{0} in Hexadecimal is {1}.");
output % 164 % Hex(164);
std::cout << output << std::endl;

The result of this example is:

164 in Hexadecimal is 0xA4.

CBuilder class

The CBuilder class is a template class where the characters used to delimit the insertion markers are declared in the template parameters when a CBuilder object is declared. By default the delimiting characters are the left and right braces ( { and } ). See Example 2 for sample code that uses different delimiter characters.

The format string is specified in the class constructor when a CBuilder object is declared. It can not be changed after it is declared, a new CBuilder object has to be constructed for each format string. The parameters however can be reset as often as needed. Simply clear out the old parameters using the ClearParameters function and then add new parameters using the % parameter adding operator.

CBuilder class members

Constructors

There are two types of constructors. The first type takes an explicit format string, and the second type loads the format string from a string resource. Both types can take up to ten optional parameters of any type that are the parameters to be inserted into the format string. If more than ten parameters are needed they can be added using the % parameter adding operator.

Syntax

CBuilder(const std::tstring &Format [, P0 ... P9] )
CBuilder(HMODULE hModule, unsigned long FormatStringID [, P0 ... P9] )

Parameters

  • Format
    • [in] The format string.
  • hModule
    • [in] Handle to the module whose executable file contains the string resource. Use NULL to specify the current application.
  • FormatStringID
    • [in] The identifier of the resource string to be loaded.
  • P0 .. P9
    • [opt] [in] Up to 10 optional parameters of any type.

Parameter management

There are two functions and one operator that can be used to manage the parameters passed into a CBuilder object.

ClearParameters

Clears out all the parameters in this CBuilder object.

Syntax

void ClearParameters(void)

GetParameterCount

Returns the number of parameters currently in this CBuilder object.

Syntax

unsigned int GetParameterCount(void)

operator %

Parameter adding operator. Used to add new/more parameters to the CBuilder object. This operator can be chained together to add multiple parameters in one statement.

Syntax

template <class T> CBuilder<Left, Right>& operator % (const T& Parameter)

Parameters

  • Parameter
    • [in] The parameter to be added, can be of any type.

Formatted output

There is one function and two operators that are used to get the formatted text out of the CBuilder object.

c_str

Returns a C style pointer to the NULL terminated formatted text string.

Syntax

const TCHAR *c_str()

operator std::tstring

Returns a std::tstring that contains the formatted text string.

Syntax

operator const std::tstring()

 

operator <<

Stream output operator. Sends the formatted output to an output stream.

Syntax

friend std::tostream& operator << (std::tostream &os, pja::CBuilder<Left, Right> &Builder)

Update

September 26, 2012 - Changed article title

March 4, 2024 - Fixed minor bug in Hex class sample code.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)