2

I have a std::string array which I need to convert to an unsigned char array so that I can use this array with third-party library which only accepts unsigned char array.

let say my array is

std::string array[3];
array[0] = "a105b";
array[1] = "c258e"
array[2] = "ff587";

I need to transfer this array into:

unsigned char cArray[3][5];

I can do hardwire the unsigned char as below:

unsigned char cArray[3][5] = {"a105b", "c258e", "ff587"};

but I was unable to find a way to do it using C++ code to transfer the data from the std::string array to the unsigned char array.

4
  • 2
    String literals include a terminating '\0', which your array has not accounted for. Is it your intention to remove those terminating characters? Commented Sep 2, 2021 at 18:08
  • 2
    @Musnazril Mustaq Khan In C++ opposite to C this declaration unsigned char cArray[3][5] = {"a105b", "c258e", "ff587"}; is incorrect. In this case the dimension of the array must be cArray[3][6]. Commented Sep 2, 2021 at 18:09
  • You can use a loop. Commented Sep 2, 2021 at 18:11
  • You can memcpy the strings, using the string::c_str method. Commented Sep 2, 2021 at 18:12

3 Answers 3

2

You could make a function that loops through the two arrays and copies from one to the other.

Example:

#include <algorithm>
#include <iostream>
#include <string>

template<size_t R, size_t N>
void foo(const std::string(&src)[R], unsigned char(&dest)[R][N]) {

    // both `src` and `dest` must be arrays with `R` rows
    // `N` is how many unsigned chars each inner array in `dest` has

    for(size_t idx = 0; idx < R; ++idx) {
        // Copy from `src[idx]` to `dest[idx]`
        // Copy at most `N` chars but no more than the length of the string + 1
        // for the null terminator:
        std::copy_n(src[idx].c_str(), std::min(N, src[idx].size() + 1), dest[idx]);

        // Add the below line if the arrays in cArray are supposed to
        // be null terminated strings:
        //dest[idx][N - 1] = '\0';
    }
}

int main() {
    std::string array[3];

    array[0] = "a105b";
    array[1] = "c258e";
    array[2] = "ff587";

    unsigned char cArray[3][5];

    foo(array, cArray);
}

I can do hardwire the unsigned char as below

unsigned char cArray[3][5] = {"a105b", "c258e", "ff587"};

No, that's not valid in C++. You would have to make the inner array [6] in C++:

unsigned char cArray[3][6] = {"a105b", "c258e", "ff587"};
Sign up to request clarification or add additional context in comments.

Comments

1

In code it could look like this:

#include <array>
#include <algorithm>
#include <cstring>
#include <string>

template<typename to_type, size_t buf_size, size_t number_of_strings>
void to_array(const std::array<std::string, number_of_strings>& input, 
              to_type (&output)[number_of_strings][buf_size])   
{
    for (std::size_t n = 0; n < number_of_strings; ++n)
    {
        const auto input_str = input[n].c_str();
        // for input string include trailing 0 on input so add one to length
        const auto copy_len = std::min(input[n].length()+1, buf_size); 
        std::memcpy(output[n], input_str, copy_len);
    }
}

int main()
{
    std::array<std::string, 3> input_array{ "a105b", "c258e", "ff587" };
    unsigned char c_array[3][6];
    to_array<unsigned char, 6>(input_array, c_array);

    return 0;
}

It showed me again that 'c' style arrays are not nice to work with. You can't return them from a function (like you can with std::array). So you have to pass the output array as parameter to the conversion function too.

1 Comment

Oh I've must been sleeping ;) Code adjusted
0

You are not permitted to assign to a plain array. You cannot define your own assignment operator for the plain array, because C++ does not allow overload of the assignment operator except as a non-static member function of a class.

One workaround may be to define an overload for a shift operator, and give a similar syntax to an input stream.

template <unsigned N>
void operator >> (std::string s, unsigned char (&a)[N]) {
    auto n = (s.size() < N) ? s.size() + 1 : N;
    std::copy_n(s.c_str(), n, a);
}

/*...*/
    unsigned char cArray[3][5];
    array[0] >> cArray[0];
    array[1] >> cArray[1];
    array[2] >> cArray[2];

Comments

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.