Reputation: 2878
I'm working in a C++ unmanaged project.
I need to know how can I take a string like this "some data to encrypt" and get a byte[] array which I'm gonna use as the source for Encrypt.
In C# I do
for (int i = 0; i < text.Length; i++)
buffer[i] = (byte)text[i];
What I need to know is how to do the same but using unmanaged C++.
Thanks!
Upvotes: 37
Views: 171385
Reputation: 48625
In C++17
and later you can use std::byte
to represent actual byte data. I would recommend something like this:
std::vector<std::byte> to_bytes(std::string const& s)
{
std::vector<std::byte> bytes;
bytes.reserve(std::size(s));
std::transform(std::begin(s), std::end(s), std::back_inserter(bytes), [](char c){
return std::byte(c);
});
return bytes;
}
Upvotes: 3
Reputation:
You might go with range-based for loop, which would look like this:
std::vector<std::byte> getByteArray(const string& str)
{
std::vector<std::byte> buffer;
for (char str_char : str)
buffer.push_back(std::byte(str_char));
return buffer;
}
Upvotes: 0
Reputation: 5542
std::string::data
would seem to be sufficient and most efficient. If you want to have non-const memory to manipulate (strange for encryption) you can copy the data to a buffer using memcpy:
unsigned char buffer[mystring.length()];
memcpy(buffer, mystring.data(), mystring.length());
STL fanboys would encourage you to use std::copy instead:
std::copy(mystring.begin(), mystring.end(), buffer);
but there really isn't much of an upside to this. If you need null termination use std::string::c_str()
and the various string duplication techniques others have provided, but I'd generally avoid that and just query for the length
. Particularly with cryptography you just know somebody is going to try to break it by shoving nulls in to it, and using std::string::data()
discourages you from lazily making assumptions about the underlying bits in the string.
Upvotes: 26
Reputation: 507055
If you just need read-only access, then c_str()
will do it:
char const *c = myString.c_str();
If you need read/write access, then you can copy the string into a vector. vectors manage dynamic memory for you. You don't have to mess with allocation/deallocation then:
std::vector<char> bytes(myString.begin(), myString.end());
bytes.push_back('\0');
char *c = &bytes[0];
Upvotes: 51
Reputation: 975
I dont think you want to use the c# code you have there. They provide System.Text.Encoding.ASCII(also UTF-*)
string str = "some text;
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(str);
your problems stem from ignoring the encoding in c# not your c++ code
Upvotes: -7
Reputation: 264471
If you just need to read the data.
encrypt(str.data(),str.size());
If you need a read/write copy of the data put it into a vector. (Don;t dynamically allocate space that's the job of vector).
std::vector<byte> source(str.begin(),str.end());
encrypt(&source[0],source.size());
Of course we are all assuming that byte is a char!!!
Upvotes: 1
Reputation:
Normally, encryption functions take
encrypt(const void *ptr, size_t bufferSize);
as arguments. You can pass c_str and length directly:
encrypt(strng.c_str(), strng.length());
This way, extra space is allocated or wasted.
Upvotes: 4
Reputation: 6128
If this is just plain vanilla C, then:
strcpy(buffer, text.c_str());
Assuming that buffer is allocated and large enough to hold the contents of 'text', which is the assumption in your original code.
If encrypt() takes a 'const char *' then you can use
encrypt(text.c_str())
and you do not need to copy the string.
Upvotes: 0
Reputation: 8937
From a std::string you can use the c_ptr() method if you want to get at the char_t buffer pointer.
It looks like you just want copy the characters of the string into a new buffer. I would simply use the std::string::copy function:
length = str.copy( buffer, str.size() );
Upvotes: 1