6

I want to convert a C-style string into a byte-vector. A working solution would be converting each character manually and pushing it on the vector. However, I'm not satisfied with this solution and want to find a more elegant way.

One of my attempts was the following:

std::vector<byte> myVector;
&myVector[0] = (byte)"MyString";

which bugs and gets me an

error C2106: '=': left operand must be l-value

What is the correct way to do this?

7 Answers 7

9

The most basic thing would be something like:

const char *cstr = "bla"
std::vector<char> vec(cstr, cstr + strlen(cstr));

Of course, don't calculate the length if you know it.

The more common solution is to use the std::string class:

const char *cstr;
std::string str = cstr;
Sign up to request clarification or add additional context in comments.

1 Comment

have to use std::vetor<byte> to store it in some binary format.
5

STL containers such as vector always take ownership, i.e. they manage their own memory. You cannot modify the memory managed internally by an STL container. For that reason, your attempt (and any similar attempt) is doomed to failure.

The only valid solution is to copy the memory or to write a new STL-style container that doesn’t take ownership of the memory it accesses.

3 Comments

You can't force an STL container to use storage you allocated, no. But you can modify the container's storage via vector::resize() or vector::reserve() :)
what about allocator_traits? i.e. if you make a custom allocator_traits and assign to a vector?
@Konrad Rudolph - I have s similar situation in which I receive several C style strings from argv (separated by space) and I wish to "concatenate" them into a single vector<char> , i.e - for the input: ./MyExe AA BB CC DD - I wish to have the vector<char> vec as follows: vec = {A,A,B,B,C,C,D,D}. At the moment my code , first , construct a std::string from the given input strings , and than convert it into a vector<char> (see below). Is there a more efficient way to do it ? int main(int argc, char** argv) { string inputStr; for (int i = 1; i < argc; ++i) { inputStr += argv[i]; } // convert
2

In case you would not like to copy the original string and would just like to iterate over it as an array of bytes, then C++20 has std::span to offer.

auto const const_bytes = std::as_bytes(std::span{str.data(), str.size()});

std::span<const std::byte> provides std::vector like iterating capabilities which I think is what you might be looking for.

Note: The original string would have to remain valid for the entire scope of std::span variable

Comments

1

Something along these lines should work

 std::vector<byte> myVector = std::vector((byte*)cstring, (byte*)ctring + strlen(cstring))

Also, this is still going to just iterate through the c string and insert the values into the vector. Like Konrad said, that's just how you have to do it since vectors manage their own memory.

Comments

0
std::vector<byte> myVector;
const char* str = "MyString";
myVector.assign( str, str+strlen(str) );

Comments

0

The most obvious question would be why you don't just use std::string:

std::string myString("MyString");

but if you really think you need a vector:

char myString[] = "MyString";

std::vector<byte> myVector(myString, myString+sizeof(myString));

You might also want to consider using std::tr1::array:

std::tr1::array<byte, sizeof("MyString")> myArray = {"MyString"};

C++ 0x will also have std::array.

1 Comment

A more obvious question to me is: where does he get the char array from in the first place (unless some library function allocates and returns it)?
-1
const char *cstr = "bla"
std::vector<char> vec;
vec.resize(strlen(cstr)+1);
strcpy(&vec[0],cstr);

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.