3

How do I convert a fixed byte array to a String in managed c++/cli ?
For example I have the following Byte array.

Byte byte_data[5];
byte_data[0]='a';
byte_data[1]='b';
byte_data[2]='c';
byte_data[3]='d';
byte_data[4]='e';

I have tried the following code
String ^mytext=System::Text::UTF8Encoding::UTF8->GetString(byte_data);

I get the following error:
error C2664: 'System::String ^System::Text::Encoding::GetString(cli::array<Type,dimension> ^)' : cannot convert parameter 1 from 'unsigned char [5]' to 'cli::array<Type,dimension> ^'

2
  • Doesn't msdn.microsoft.com/en-us/library/ezh7k8d5.aspx do this for you? Give or take signed vs unsigned. Commented Jan 28, 2013 at 2:24
  • @ta.speot.is Good catch! If you use the constructor that takes an encoding parameter (and set it to System.Text::UTF8Encoding). Commented Jan 28, 2013 at 2:32

3 Answers 3

3

Here is one option:

array<Byte>^ array_data = gcnew array<Byte>(5);
for(int i = 0; i < 5; i++)
    array_data[i] = byte_data[i];
System::Text::UTF8Encoding::UTF8->GetString(array_data);

Not compiled but I think you get the idea.

Or use the String constructor, as indicated by @ta.speot.is, with encoding set to System.Text::UTF8Encoding.

Sign up to request clarification or add additional context in comments.

9 Comments

Unfortunately I have already declared the byte array as Byte byte_data[5] and all my functions need to work on the assumption that data is in byte_data[X]. I need a method to convert this byte array and not a new one as you have declared.
You need to create a managed copy of the array right before calling GetString. The rest of your code can stay the same.
This seems tedious, But will work...Is there another efficient solution than by copying each byte manually?
The call expects a managed array so no. Create a helper function if you want. For one, how would GetString know the size of byte_data? It is not null-terminated.
@PeterH: Marshal::Copy. You have to copy the data. It's not slow, but as always, run your own tests before assuming it will or will not work for you.
|
2

Arm yourself with some knowledge about casting between pointers to signed and unsigned types and then you should be set to use String::String(SByte*, Int32, Int32). It might also pay to read the Remarks on the page, specifically around encoding.

I've reproduced the sample from the page here:

// Null terminated ASCII characters in a simple char array 
char charArray3[4] = {0x41,0x42,0x43,0x00};
char * pstr3 =  &charArray3[ 0 ];
String^ szAsciiUpper = gcnew String( pstr3 );
char charArray4[4] = {0x61,0x62,0x63,0x00};
char * pstr4 =  &charArray4[ 0 ];
String^ szAsciiLower = gcnew String( pstr4,0,sizeof(charArray4) );

// Prints "ABC abc"
Console::WriteLine( String::Concat( szAsciiUpper,  " ", szAsciiLower ) );

// Compare Strings - the result is true
Console::WriteLine( String::Concat(  "The Strings are equal when capitalized ? ", (0 == String::Compare( szAsciiUpper->ToUpper(), szAsciiLower->ToUpper() ) ? (String^)"TRUE" :  "FALSE") ) );

// This is the effective equivalent of another Compare method, which ignores case
Console::WriteLine( String::Concat(  "The Strings are equal when capitalized ? ", (0 == String::Compare( szAsciiUpper, szAsciiLower, true ) ? (String^)"TRUE" :  "FALSE") ) );

2 Comments

How do I do the encoding to ascii. At the moment it's doesn't appear to be accepting line breaks? I'm assuming its an encoding issue. See post below. Doesn't seem to like String ^mytextutf8=System::Text::ASCIIEncoding::ASCII->GetChars(pstr3);
@PeterH There is another overload of String::String that takes an encoding.
0

For those interested in another working solution. I used the notes of ta.speot.is and developed a working solution,You should be able to use this solution or that provided by Rasmus.

Byte byte_data[5];
byte_data[0]='a';
byte_data[1]='b';
byte_data[2]='c';
byte_data[3]='d';
byte_data[4]='e';

char *pstr3 =  reinterpret_cast<char*>(byte_data);
String^ example1 = gcnew String( pstr3 );//Note: This method FAILS if the string is not null terminated
                                        //After executing this line the string contains garbage on the end example1="abcde<IqMŸÖð"

String^ example2 = gcnew String( pstr3,0,sizeof(byte_data));    //String Example 2 correctly contains the expected string even if it isn't null terminated

2 Comments

sizeof(pstr3)+1 is not correct, it will only be 5 by coincidence (only when sizeof(char *) == 4, which depends on your architecture). I think you wanted sizeof(byte_data).
@ta.speot.is Thanks Nice Spot.. This fixed the display bug/carriage return problem. Not exactly sure why but looks good. I have edited the post above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.