字符串向量到 uint8_t C++
String vector to uint8_t C++
我有一个向量,其中的字符串表示位如下:
string str1[] = { "0b01100101", "0b01100101", "0b01011101", "0b11001111"}
我需要添加到 uint8_t 位向量的确切值:
uint8_t str2[] = { 0b01100101, 0b01100101, 0b01011101, 0b11001111}
最终结果应该与上面完全一样。
如果有人知道我该怎么做,我将不胜感激。
不幸的是,没有标准函数来解析带有“0b”前缀的二进制字符串。
您可以使用旧的 std::strtoul
(1 行调用 std::strtoul
和 5 行错误检查):
#include <algorithm>
#include <stdexcept>
#include <cstdlib>
#include <string>
uint8_t binary_string_to_uint8(std::string const& s) {
if(s.size() != 10 || '0' != s[0] || 'b' != s[1])
throw std::runtime_error("Invalid bit string format: " + s);
char* end = 0;
auto n = std::strtoul(s.c_str() + 2, &end, 2);
if(end != s.c_str() + s.size())
throw std::runtime_error("Invalid bit string format: " + s);
return n;
}
int main() {
std::string str1[] = { "0b01100001", "0b01100101", "0b01011101", "0b11001111"};
uint8_t str2[sizeof str1 / sizeof *str1];
std::transform(std::begin(str1), std::end(str1), std::begin(str2), binary_string_to_uint8);
}
请注意,这些可能会输出与算法几乎相同或相同的程序集,因此几乎总是首选类似于其他答案的算法。尽管如此,这里还有一些使用循环的选项:
std::stoul
- 至少需要 C++11。我们也不在这里进行边界检查,我们假设所有字符串的大小都是 >=
2.
std::string str1[] = {"0b01100101", "0b01100101", "0b01011101", "0b11001111"};
const size_t sz = sizeof str1 / sizeof *str1;
uint8_t str2[sz];
for (size_t i = 0; i < sz; ++i)
str2[i] = static_cast<uint8_t>(std::stoul(&str1[i][2], nullptr, 2));
因为实际上这些很可能是可变大小的数组,您最好在此处使用实际的 vector
类型。
std::vector<std::string> vs;
// add a bunch of stuff to vs
...
std::vector<uint8_t> vi;
vi.reserve(vs.size());
for (const auto &s : vs)
vi.push_back(static_cast<uint8_t>(std::stoul(&s[2], nullptr, 2)));
我有一个向量,其中的字符串表示位如下:
string str1[] = { "0b01100101", "0b01100101", "0b01011101", "0b11001111"}
我需要添加到 uint8_t 位向量的确切值:
uint8_t str2[] = { 0b01100101, 0b01100101, 0b01011101, 0b11001111}
最终结果应该与上面完全一样。 如果有人知道我该怎么做,我将不胜感激。
不幸的是,没有标准函数来解析带有“0b”前缀的二进制字符串。
您可以使用旧的 std::strtoul
(1 行调用 std::strtoul
和 5 行错误检查):
#include <algorithm>
#include <stdexcept>
#include <cstdlib>
#include <string>
uint8_t binary_string_to_uint8(std::string const& s) {
if(s.size() != 10 || '0' != s[0] || 'b' != s[1])
throw std::runtime_error("Invalid bit string format: " + s);
char* end = 0;
auto n = std::strtoul(s.c_str() + 2, &end, 2);
if(end != s.c_str() + s.size())
throw std::runtime_error("Invalid bit string format: " + s);
return n;
}
int main() {
std::string str1[] = { "0b01100001", "0b01100101", "0b01011101", "0b11001111"};
uint8_t str2[sizeof str1 / sizeof *str1];
std::transform(std::begin(str1), std::end(str1), std::begin(str2), binary_string_to_uint8);
}
请注意,这些可能会输出与算法几乎相同或相同的程序集,因此几乎总是首选类似于其他答案的算法。尽管如此,这里还有一些使用循环的选项:
std::stoul
- 至少需要 C++11。我们也不在这里进行边界检查,我们假设所有字符串的大小都是 >=
2.
std::string str1[] = {"0b01100101", "0b01100101", "0b01011101", "0b11001111"};
const size_t sz = sizeof str1 / sizeof *str1;
uint8_t str2[sz];
for (size_t i = 0; i < sz; ++i)
str2[i] = static_cast<uint8_t>(std::stoul(&str1[i][2], nullptr, 2));
因为实际上这些很可能是可变大小的数组,您最好在此处使用实际的 vector
类型。
std::vector<std::string> vs;
// add a bunch of stuff to vs
...
std::vector<uint8_t> vi;
vi.reserve(vs.size());
for (const auto &s : vs)
vi.push_back(static_cast<uint8_t>(std::stoul(&s[2], nullptr, 2)));