Vic
Vic

Reputation: 2878

Get bytes from std::string in C++

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

Answers (9)

Galik
Galik

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

user11262312
user11262312

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

Christopher Smith
Christopher Smith

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

Johannes Schaub - litb
Johannes Schaub - litb

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

Hippiehunter
Hippiehunter

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

Loki Astari
Loki Astari

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

user3458
user3458

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

Mark
Mark

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

Nick Haddad
Nick Haddad

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

Related Questions