You are here:

C++/casting a colorDialog result to a string

Advertisement


Question
Hi Ralph,

Sorry for the noob question last time, but im a noob so i have noob questions..
This question is less of a noob question, atleast i think so.

The problem is, I want to show the colour picked by the user as a hex value/RBG thing but C++ does not let me cast the colorDialog1->Color to a string.

like this:
label1->Text = colorDialog1->Color;

or
label1->Text = String::ToString(colorDialog1->Color);

or char::tostring, things like that

none of them worked, I even tried things with the RGB(int, int, int) thing but with no results.

There just HAS to be a way to display the actual value of the colour instead of changing the colour of things with the colour dialog, i tried that aswell, it works as expected.

thanx in advance,
harold

Answer
The compiler cannot cast integers to strings, this is not allowed. Mostly inbuilt casting allows converting between integer types or related types or types with similar qualifications. Also the compiler does not know of your type String - C++ has no inbuilt type String. The nearest inbuilt type is an array of char (which are terminated with a zero character value), otherwise there is the standard library class std::string, but this is a class defined like any other and the compiler is not required to have any special knowledge of classes in the standard library.

The Win32 SDK macro RGB just ensures the red, green and blue component byte values of an RGB triplet are packed into the correct portions of a 32-bit integer type.

If you are using C-strings then you can use the POSIX function itoa. Note this is not a standard C or C++ library function so may not be included with your compiler - especially for compilers targeting MS Windows platforms. MS VC++ supports it but would prefer that you use the form prefixed with an _ (underscore): _itoa - showing it is an extension to the standard, or a more secure (MS specific) version _itoa_s.

The declaration for itoa and _itoa is as follows:

char *_itoa
(
  int value,
  char *str,
  int radix
);

value is the integer value you wish to convert to a string. Note that it is a signed integer type. str is a pointer to the char array (zero terminated) string to hold the result and radix is the number base you wish the value to be represented as in the range 2 to 36. Note that the size of the char array needs to be big enough to store the result (upto these 33 characters I think, including the terminating zero). Providing too few characters for the value represented will cause a buffer overrun - a very common cause of security problems. MS also provide 64 bit and wide character C-string variations - in these cases the str buffer needs to be 65 characters. They all return a pointer to str.

The secure version has the following declaration:

errno_t _itoa_s
(
  int value,
  char *buffer,
  size_t sizeInCharacters,
  int radix
);

The differences are the additional sizeInCharacters parameter that tells the function how many characters it can write into str, and returning 0 for success or an error code. Also the function will invoke an invalid parameter handler function if any of the parameters are invalid (i.e. str is NULL or sizeInCharacters <= 0 or too small for the result or radix < 2 or > 36), which can be replaced using the MS specific _set_invalid_parameter_handler.

The next way to achieve what you wish is to use the C++ standard library iostreams - in particular a std::ostringstream (include sstream):

std::ostringstream os;

os << rgbValue;

std::cout << os.str();

std::ostringstream uses the std::string type as its string. If you wish to use C-style strings then you can use the std::ostrstream type (include strstream):

std::ostrstream ostrm;

ostrm << rgbValue << std::ends;

char * rgbStr = ostrm.str();

Things to note are:

- That the char buffer array is dynamically allocated by std::ostrstream in this mode. Asking for a pointer to the buffer, as I do at the end for rgbStr, causes the buffer to be frozen meaning it cannot be manipulated and thus will not be re-allocated out from under external references such as rgbStr. To un-freeze the buffer you pass false to the freeze member function:

ostrm.freeze( false );

- That you need to terminate the C-string using std::ends.

- That you can also use a fixed buffer std::ostrstream which it is passed during construction:

char buffer[1000]; // can store up to 999 characters

std::ostrstream  fixed_buffer_ostrm( buffer );

In this case the std::ostrstream instance is never responsible for the management of the buffer.

You can of course use all the C++ IOStream formatting facilities when using the string stream types.

A third possibility is to use the lexical_cast from the Boost C++ libraries (see http://www.boost.org/ and http://www.boost.org/libs/conversion/lexical_cast.htm) which allow doing what you originally wished to do using a format similar to C++ casts like static_cast<>():

DWORD rgbInt( RGB(123,123,123) );

std::string rgbString( boost::lexical_cast<std::string>(rgbInt) );

You will of course need to download and install the Boost libraries, specifically the Boost conversion library. As far as I know this is a header file only library so will not force you to build any object code (.LIB files) or dynamic (DLL files) libraries.

For more information please refer to your C++ standard library, compiler runtime library and Boost documentation. For MS VC++, documentation can be found in the MSDN library, online at http://msdn.microsoft.com/, specifically http://msdn.microsoft.com/library/. If you do not have a good C++ standard library reference then I recommend the book "The C++ Standard Library A Tutorial and Reference" by Nicolai M. Josuttis.

Finally, please note that I have not compiled the code snippet examples so I'll apologise now for any typos and errors they may contain - sorry!  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.