Reputation: 461
I have a small trouble in converting std::array to std::string. I have something like that:
std::stringstream message;
message << 12345 << '\0' << '\0'
<< '\0' << "SOMETHING IMPORTANT" << '\0';
Next I'm using boost::asio::io::socket to send the message.str()
My server is receiving the message and saving it to std::array<char, 1024>
, but the problem is that I can't extract just the "SOMETHING IMPORTANT".
I've tried to use std::array.begin()
which returns only 12345
, I also tried std::array.data() which returns my data + a lot of junk. I believe it's not a hard task, but I got stuck on it.
Upvotes: 2
Views: 1956
Reputation: 131
well, recently i tried to pass some pic data in one process to another, I have tested them below:
Suppose you have data like this std::array<char, 6*1024*1024> curImg = xxxx
,
you just need to do this:
std::string picdata(std::begin(curImg.data()), std::end(curImg.data()));
you will get your picdata, then you can convert it to CV::MAT
, like this cv::Mat yuv422Img(height, width,CV_8UC2, (unsigned char*)picdata.c_str());
.
Upvotes: 0
Reputation: 392893
What you are looking for is parsing.
In the literal sense of your question title, you would convert an array to string like this:
std::array<char, 1024> buf;
std::string value(buf.data(), bytes_transferred);
Where bytes_transferred is the known size of the data in the buffer (so you don't have to rely on buf.size()
, which would always be 1024).
However, since you're basically parsing from a stream, you can use one:
std::stringstream ss;
ss.write(buf.data(), bytes_transferred);
And then you can use the stream as you would normally:
unsigned n;
ss >> n;
Or
std::string important;
std::getline(ss, 1024, '\0');
To take it to another level you might use a proper parser to convert the access of your buffer. E.g. using Boost Spirit:
#include <array>
#include <boost/asio.hpp>
#include <boost/fusion/adapted.hpp>
#include <boost/spirit/home/x3.hpp>
#include <iomanip>
#include <sstream>
namespace x3 = boost::spirit::x3;
int main() {
std::array<char, 1024> buf;
size_t bytes_transferred;
static constexpr char NUL = '\0';
{
std::stringstream message;
message << 12345 << NUL << NUL << NUL << "SOMETHING IMPORTANT" << NUL
<< "trailing";
// emulating the asio read:
message.read(buf.data(), buf.size());
bytes_transferred = message.gcount();
}
// now we can do the desired parsing:
unsigned value;
std::string important;
auto bound_attributes = std::tie(value, important);
auto f = begin(buf), l = f + bytes_transferred;
if (x3::parse(f, l,
x3::uint_ >> NUL >> NUL >> NUL >> *~x3::char_(NUL) >> NUL,
bound_attributes)) {
std::cout << "Sucessfully parsed message: " << value << " and "
<< std::quoted(important) << "\n";
} else {
std::cout << "Failed to parse parse";
}
if (f != l) {
auto bytes_remaining = std::distance(f,l);
std::cout << "Remaining in buffer: " << bytes_remaining << " bytes\n";
std::rotate(buf.begin(), f, l); // put at front of buffer
bytes_transferred = bytes_remaining; // just for example
std::cout << "Buffer contents: "
<< std::quoted(std::string(buf.begin(), bytes_remaining))
<< "\n";
}
}
Which prints
Sucessfully parsed message: 12345 and "SOMETHING IMPORTANT"
Remaining in buffer: 8 bytes
Buffer contents: "trailing"
Upvotes: 1