I need to use a function func(uint8_t* buffer, uint size)
; supposing I can't change its parameters, I want to pass it a string.
I have a vector<string>
that I must convert to uint8_t*
and then read it and convert it back to vector<string>
.
I tried this code for reading (printing) the vector.data()
output but it prints garbage:
#include <cstdint>
#include <string>
#include <vector>
#include <iostream>
int main() {
std::string a1 = {"ath"};
std::cout <<"1: "<< a1<<" end\n";
std::vector<std::string> vec;
vec.push_back(a1);
uint8_t *ptr = reinterpret_cast<uint8_t*>(vec.data());
std::cout <<"2: "<< ptr[0]<<" end\n";
}
output:
1: ath end
2: � end
questions:
- why this doesn't work?
- I saw in some links that they init a
std::string
withchar*
array like this:
char *ptr={'a'};
std::string myStr(ptr);
I suppose this works because of added '\0', is this related to my problem?
CodePudding user response:
why this doesn't work?
This can't work, because a std::string
is not just a contiguous piece of memory containing nothing but the characters in the string. You're simply mistaken about what std::string
is!
Using a vector here is plain not the right approach. A vector does not contain your string's contents. Just the std::string
objects themselves, which are not the string data.
Instead, you want to make one long std::string
:
std::string foo {"foo"};
std::string bar {"bar "};
std::string baz {"bazaz"};
std::string complete = foo bar baz;
auto* whole_cstring = reinterpret_cast<uint8_t*>(complete.c_str());
// call your C-string-accepting function
func(whole_cstring, complete.length());
If you actually do have a std::vector
of std::string
s to begin with, the concatenation can be done in a simple loop:
std::vector<std::string> my_vector_of_strings;
// insert strings into the vector
/// … ///
std::string complete;
for(const auto& individual_string : my_vector_of_strings) {
complete = individual_string;
}
auto* whole_cstring = reinterpret_cast<uint8_t*>(complete.c_str());
// call your C-string-accepting function
func(whole_cstring, complete.length());
… missing \0 … I suppose this works because of added '\0', is this related to my problem?
No, that's completely unrelated.
CodePudding user response:
I have a vector that I must convert to uint8_t*
std::vector<std::string> vec;
"Converting" has a relatively strong definition in the C (and other languages) world. If I understand what you mean, I'd suggest the following:
#include <string>
#include <vector>
#include <algorithm>
int main(){
std::vector<std::string> vec;
// populate
std::vector<uint8_t*> vec2(vec.size());
std::transform(begin(vec), end(vec), begin(vec2), [](auto& s){ return reinterpret_cast<unsigned char*>(s.data()); });
}
Alternatively, if possible, you can use a std::basic_string<uint8_t>
instead of std::string
(a/k/a std::basic_string<char>
) to avoid reinterpreting its content.