6

I have an array of floats with a fixed length. Now I want to convert that array to a binary string.

I cannot use const char * because my string will contain null-bytes. How would I use memcpy in that case? I have already tried a reinterpret_cast<string *>, but that won't work because the string is also/only storing pointers to the begin and end of the data (correct me if I am wrong).

I'm already constructing an empty string:

string s;
s.resize(arr_size);

But how would I copy an array of floats to that string?

Basically, I want to dump the memory region of a fixed float array to a string.

Don't be to hard with me, I'm still learning c++

3 Answers 3

7

Like this:

#include <algorithm>
#include <string>

float data[10]; // populate

std::string s(sizeof data);
char const * p = reinterpret_cast<char const *>(data);

std::copy(p, p + sizeof data, &s[0]);

Note that sizeof data is the same as 10 * sizeof(float), i.e. the number of bytes in the array.

Update: As suggested by James, you can do even better and write it all in one go:

char const * p = reinterpret_cast<char const *>(data);
std::string s(p, p + sizeof data);  // beginning + length constructor

Or even:

#include <iterator>

std::string s(reinterpret_cast<char const *>(std::begin(data)),  // begin + end
              reinterpret_cast<char const *>(std::end(data)));   // constructor
Sign up to request clarification or add additional context in comments.

8 Comments

If you use the two iterator constructor of string, you don't have to worry about the size.
I'm getting warning C4996 (but I think it's ok) .. but I'm also getting error C3892 - you cannot assign to a variable that is const .. might that be because s.data() is const?
@H2CO3 How's that? Either you are calling it with the definition of the array, in which case, you use std::begin() and std::end() (or the equivalents in your tool kit in pre-C++11), or you're in a function which has been passed a pointer, in which case, the function also takes either a length (in elements) or an end pointer.
@JamesKanze Disregard... Forgot about std::begin() and std::end()... Sorry.
and how do you print this using printf?
|
4

Getting all of the bytes of the array into a string is easy:

std::string
bitwiseDump( float const* begin, float const* end )
{
    return std::string( reinterpret_cast<char const*>( begin ),
                        reinterpret_cast<char const*>( end ) );
}

But why? There's nothing you can do with the string except copy it back into an array of the same type. (And even for that use, std::vector<char> or std::vector<unsigned char> would be more natural. And less obfuscating.)

7 Comments

I'm using a graphics engine which needs the vertex data as a binary string :)
This should be a template :-)
You mean it takes an std::string with the binary data as a parameter? That's a very poorly designed interface.
@KerrekSB I more or less agree, and I started to write it as such. On the other hand, it's easy to convert into a template if the need arises, and the use is so limited that it almost certainly won't.
@KerrekSB On the other hand, the template might become interesting if you define the function std::string bitwiseDump( float (&array)[N} ), with a template argument size_t N.
|
1

Take a look at this...

#include <iostream>
#include <array>
#include <string>

int main()
{
    std::string floatString;
    std::array<float, 5> data = {1.1f, 2.2f, 3.3f, 4.4f, 5.5f};

    for (auto& element : data)
        floatString.append(std::to_string(element));

    std::cout << floatString;
    std::cin.get();
}

1 Comment

My fault, I also didn't read that the OP wants to get it in binary representation...

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.