views:

1158

answers:

5

Hello everyone, I'm trying to do something simple here. When I execute the following code in Visual Studio 2008 using the unicode character set, xmlString is correct.

Unfortunately I need to convert the CString to a unsigned char*. Using the code below, ucStr becomes "<" (i.e. the first character of xmlString).

How should I convert the CString to an unsigned char* and retain all the information?

     CString xmlString;
  xmlString.Format( _T("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><gateway><config-read><%s /></config-read></gateway>"), keyName);

  unsigned char * ucStr = reinterpret_cast<unsigned char *> (xmlString.GetBuffer());
  pgIRequest->SendXmlData( "dgv/gateway.xml", ucStr, xmlString.GetLength() + 1) ;
A: 

I assume "SendXmlData" wants the number of bytes and not the number of characters.

If so, you want to change "GetLength() + 1" to "(GetLength() + 1)*sizeof(xmlString[0])".

KenE
" ucStr becomes '<' " -- yes, if this was observed in the debugger, then KenE's answer might be helpful. But if this was noted at the receiver (or similar), then there should have been much more data available.
Pukku
Pukku is right, the length of the buffer in SendXmlData has nothing to do with my issue - see the code that I got working below.
Jordan L. Walbesser
Well now that the string has actually been *converted*, xmlString.GetLength() is also fine - it should return the same as ucStr.GetLength() of your working version. So it's not really proof against KenE's suggestion. Btw, make sure you test also with such input that cannot be represented in ASCII.
Pukku
+1  A: 

I think you want wcstombs, or, rather, its more secure counterpart wcstombs_s.

Pukku
+4  A: 

I find the simplest is to use the CStringA constructor, like this:

 CString xmlString;
 xmlString.Format( _T("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><gateway><config-read><%s /></config-read></gateway>"), "test");

 printf("%s\n",xmlString );  // fails "<"

 //unsigned char * ucStr = reinterpret_cast<unsigned char *> (xmlString.GetBuffer());

 CStringA ucStr( xmlString );

 printf("%s\n",ucStr );   // works!
ravenspoint
+1. Yes, this is simpler than using the plain C functions.
Pukku
That will not "retain all the information". Ie. it will strip all non-western characters. You need to convert to UTF-8.
Nemanja Trifunovic
A: 

Here's the code that finally worked:

CString xmlString;
  xmlString.Format( _T("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><gateway><config-read><%s /></config-read></gateway>"), keyName);
  CStringA ucStr( xmlString );
  unsigned char * ucStr2 = reinterpret_cast<unsigned char *> (ucStr.GetBuffer());
  pgIRequest->SendXmlData( "dgv/gateway.xml", ucStr2, xmlString.GetLength() + 1) ;// target on gateway to download
Jordan L. Walbesser
+3  A: 

This codes snippet may not work when your 'keyName' variable starts to contain characters that are not representable in the ISO-8859-1 encoding. For this I recommend creating a string with UTF-8 as encoding value, convert to UTF-8 byte stream using WideCharToMultiByte using the CP_UTF8 codepage and send out resulting utf8 byte stream.

vividos
+1. My point exactly (in comments to KenE's answer).
Pukku