Chris
Chris

Reputation: 115

Adding elements of a wchar_t[] string to array<wchar_t>^ without for loop

I am writing a vc++ CLR form project which will control my robot via the serial port. The robot expects an ASCII command as follows: First byte is a character between A and Z which determines the command to execute, the second character is a + or - sign, then there are exactly 5 numbers. If the number to send is less than 5 digits then it is padded with zeros at the start.

I am using System::IO::Ports::SerialPort to communicate with the COM port which has the following prototype:

public:
void Write(
    array<wchar_t>^ buffer, 
    int offset, 
    int count
)

Since I need to pad the number so it is exactly 5 digits, I am using sprintf. (I am still learning c++ and have not had much experience with String::Format yet, but I assume I can do the same thing there just as easily - but for now I want to do it using these arrays, for the sake of learning).

sprintf returns the string of wchar_t, I now need to add these wchar_t to an < array > to pass to the function however I am having trouble find an elegant solution to this. The solution I have works, however the for loops feel really hacky to me:

int DeltaForm::setThetas(int th1, int th2, int th3)
{
// Cannot write more than 5 digits
if (th1 < 1000 && th2 < 1000 && th3 < 1000)
{
    wchar_t commandBuffer[8];
    array<wchar_t>^ buffer = gcnew array<wchar_t>(8);

    _snwprintf_s(commandBuffer, 8, 7, L"B+%05d", th2*100);
    for (int i = 0; i < 8; i++)
    {
        buffer->SetValue(commandBuffer[i], i);
    }
    this->serialComms->Write(buffer, 0, 7);

    _snwprintf_s(commandBuffer, 8, 7, L"A+%05d", th1*100);
    for (int i = 0; i < 8; i++)
    {
        buffer->SetValue(commandBuffer[i], i);
    }
    this->serialComms->Write(buffer, 0, 7);

    _snwprintf_s(commandBuffer, 8, 7, L"C+%05d", th3*100);
    for (int i = 0; i < 8; i++)
    {
        buffer->SetValue(commandBuffer[i], i);
    }
    this->serialComms->Write(buffer, 0, 7);
}
else
{
    return 0;
}
}

I have had a look through the array class but could not find any methods which would help me. Is there a simpler, more elegant way to populate an array?

Thanks

Upvotes: 2

Views: 1791

Answers (1)

mockinterface
mockinterface

Reputation: 14880

If you pin a pointer to the array you can treat it natively, for example:

array<wchar_t>^ buffer = gcnew array<wchar_t>(8);
pin_ptr<wchar_t> p = &buffer[0];
_snwprintf_s(p, 8, 7, L"B+%05d", th2*100);
this->serialComms->Write(buffer, 0, 7);

I'd also like to elaborate on the point @Adriano made. It seems that you are using Managed C++ throughout your code, and while it was specifically designed to mix C++ with the CLR,it is better to stick to one methodology.

System::String^ command = String::Format("B+{0:00000}", th2*100);
array<Byte>^ command_buffer = System::Text::Encoding::Unicode->GetBytes(command);

The example uses Unicode because UTF-16 is used by the Windows operating system to represent wchar values, but you should switch that to ASCII if that's what expected on the wire.

Upvotes: 2

Related Questions