< C++ .NET Formatting 7 | Index #1 | Index # 2 | C++ .NET Formatting 9 >


 

 

Playing With C++ .NET Formatting 8

 

 

The following are the topics available in this part.

  1. Enumeration Format Strings (continue)

  2. Customizing Format Strings

  3. Adding Custom Format Strings for Custom Types

  4. Adding Custom Format Strings to Existing Types

 

 

The following code sample demonstrates using an enumeration to represent named values and another enumeration to represent named bit fields.

// testprog.cpp : main project file.

// Example of the DayOfWeek enumeration

#include "stdafx.h"

 

using namespace System;

 

enum class Days

{

   Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday

};

 

enum class BoilingPoints

{ Celcius = 100, Fahrenheit = 212 };

 

[FlagsAttribute]

 

enum class Colors

{ Red = 1, Green = 2, Blue = 4, Yellow = 8 };

int main()

{

      Type^ weekdays = Days::typeid;

      Type^ boiling = BoilingPoints::typeid;

     

      Console::WriteLine("The days of the week, and their corresponding values in the Days Enum are:");

      Array^ a = Enum::GetNames(weekdays);

      Int32 i = 0;

      do

      {

            Object^ o = a->GetValue(i);

            Console::WriteLine("{0,-11}= {1}", o->ToString(), Enum::Format(weekdays, Enum::Parse(weekdays, o->ToString()), "d"));

      } while (++i < a->Length);

 

      Console::WriteLine();

      Console::Write("Enums can also be created which have values that\nrepresent some meaningful amount.");

      Console::WriteLine(" The BoilingPoints Enum\ndefines the following items, and corresponding values:");

 

      i = 0;

      Array^ b = Enum::GetNames(boiling);

 

      do

      {

            Object^ o = b->GetValue(i);

            Console::WriteLine("{0,-11}= {1}", o->ToString(), Enum::Format(boiling, Enum::Parse(boiling, o->ToString()), "d"));

      } while (++i < b->Length);

 

      Array^ c = Enum::GetNames(Colors::typeid);

      Colors myColors = Colors::Red | Colors::Blue | Colors::Yellow;

      Console::WriteLine();

      Console::Write("myColors holds a combination of colors. Namely:");

 

      for (i = 0; i < 3; i++)

         Console::Write(" {0}", c->GetValue(i));

      Console::WriteLine();

 

      return 0;

}

 

Output:

 

 

 

 

 

 

C++ .NET formatting - code sample demonstrates using an enumeration to represent named values and another enumeration to represent named bit fields

 

Customizing Format Strings

 

The .NET Framework supports extending its built-in formatting mechanism so you can create your own ToString method that accepts user-defined format strings, or create a format provider that invokes your own Format method to perform custom formatting of a type. You create your own ToString method by implementing the IFormattable interface, and your own Format method by implementing the ICustomFormatter and IFormatProvider interfaces. The information in this section is limited to adding custom format strings to user-defined types and existing base types, but the principles described can be applied to any type.

 

Adding Custom Format Strings for Custom Types

 

If you create your own custom type, you can add support for processing your own custom format strings by implementing the IFormattable interface and that interface's ToString method. This means you can control what format strings are recognized by your custom type. The benefit of implementing the IFormattable interface instead of merely adding a ToString method to your custom type is that you can guarantee users of your ToString method a predefined calling syntax and return type.

The ToString method of the IFormattable interface takes a format string parameter and a format provider parameter. If the format string parameter is an empty string or null (Nothing in Visual Basic), perform default formatting. If the format provider is null, use a default format provider. If a custom format string is passed to your custom version of ToString, perform the appropriate formatting; otherwise, call a suitable .NET Framework method to perform standard formatting.

 

Adding Custom Format Strings to Existing Types

 

You can control how an existing base type is formatted, and provide additional codes for formatting, by creating a format provider class that implements ICustomFormatter and IFormatProvider. When you pass a format provider to the ToString method of a base type, the base type uses the passed format provider to define its formatting rules rather than the default format provider. To create a custom format provider, you should do the following:

  1. Define a class that implements the two previously mentioned interfaces and overrides GetFormat and Format.

  2. Pass that class into a method (like String.Format) that takes the IFormatProvider as a parameter. Doing so causes String.Format to recognize the custom format scheme defined in the new format provider class.

The following code sample illustrates the use of ToString, taking a String and an IFormatProvider as parameters.

// testprog.cpp : main project file.

// Illustrates the use of ToString

#include "stdafx.h"

 

using namespace System;

 

public ref class Temperature: public IFormattable

{

   // IFormattable.ToString implementation.

   public:

      virtual String^ ToString(String^ format, IFormatProvider^ provider)

      {

         if (format != nullptr)

         {

           if (format->Equals("F"))

           {

              return String::Format("{0}'F", this->Value.ToString());

           }

           if ( format->Equals("C"))

           {

              return String::Format("{0}'C", this->Celsius.ToString());

           }

         }

         return m_value.ToString(format, provider);

      }

 

   protected:

      // The value holder

      double m_value;

      public:

        property double Value

        {

           double get()

           { return m_value; }

           void set(double value)

           { m_value = value; }

        }

        property double Celsius

        {

           double get()

           { return (m_value - 32.0) / 1.8; }

           void set(double value)

           { m_value = 1.8 * value + 32.0; }

        }

};

 

int main()

{

      return 0;

}

 

Output: none

The following code example converts a Single value to a String with the ToString method, using a formatting String.

// testprog.cpp : main project file.

// Example for the Single::ToString( ) methods.

#include "stdafx.h"

 

using namespace System;

using namespace System::Globalization;

 

int main()

{

   float singleValue = 11876.54321F;

   String^ format = "  {0,-30}{1}";

   Console::WriteLine( "This example of\n"

   "  Single::ToString( ), \n"

   "  Single::ToString( String* ),\n"

   "  Single::ToString( IFormatProvider* ), and \n"

   "  Single::ToString( String*, IFormatProvider* )\n"

   "generates the following output when run in the [{0}] "

   "culture. \nA Single number is formatted with various "

   "combinations of format \nstrings and IFormatProvider.", CultureInfo::CurrentCulture->Name );

 

   // Format the number without and with format strings.

   Console::WriteLine( "\nIFormatProvider is not "

   "used; the default culture is [{0}]:", CultureInfo::CurrentCulture->Name );

   Console::WriteLine( format, "No format string:", singleValue.ToString() );

   Console::WriteLine( format, "'N5' format string:", singleValue.ToString( "N5" ) );

   Console::WriteLine( format, "'E' format string:", singleValue.ToString( "E" ) );

   Console::WriteLine( format, "'E5' format string:", singleValue.ToString( "E5" ) );

   // Create a CultureInfo object for another culture. Use

   // [Dutch - The Netherlands] unless the current culture

   // is Dutch language. In that case use [English - U.S.].

   String^ cultureName = CultureInfo::CurrentCulture->Name->Substring( 0, 2 )->Equals( "nl" ) ? (String^)"en-US" : "nl-NL";

   CultureInfo^ culture = gcnew CultureInfo( cultureName );

   // Use the CultureInfo object for an IFormatProvider.

   Console::WriteLine( "\nA CultureInfo object "

   "for [{0}] is used for the IFormatProvider: ", cultureName );

   Console::WriteLine( format, "No format string:", singleValue.ToString( culture ) );

   Console::WriteLine( format, "'N5' format string:", singleValue.ToString( "N5", culture ) );

   Console::WriteLine( format, "'E' format string:", singleValue.ToString( "E", culture ) );

   // Get the NumberFormatInfo object from CultureInfo, and

   // then change the digit group size to 2 and the digit

   // separator to '_'.

   NumberFormatInfo^ numInfo = culture->NumberFormat;

   array<Int32>^sizes = {2};

   numInfo->NumberGroupSizes = sizes;

   numInfo->NumberGroupSeparator = "_";

   // Use a NumberFormatInfo object for IFormatProvider.

   Console::WriteLine( "\nA NumberFormatInfo object with digit "

   "group size = 2 and \ndigit separator = '_' is used "

   "for the IFormatProvider:" );

   Console::WriteLine( format, "'N' format string:", singleValue.ToString( "N", culture ) );

   Console::WriteLine( format, "'E' format string:", singleValue.ToString( "E", culture ) );

 

   return 0;

}

 

Output:

C++ .NET formatting - code example that converts a Single value to a String with the ToString method, using a formatting String

 

 

 

 

 

Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7 | Part 8 | Part 9


< C++ .NET Formatting 7 | Index #1 | Index # 2 | C++ .NET Formatting 9 >