tôi nghĩ rằng bất kỳ câu trả lời kinh điển (wrtcác nốt tiền thưởng) sẽ bao gồm một số giai đoạn khác nhau trong các giải pháp: kiểm tra
- Lỗi cho đầu vào hợp lệ
- kiểm tra chiều dài và
- kiểm tra nội dung dữ liệu
- Yếu tố chuyển đổi tạo
- Output
Cho lần thứ e hữu ích của các chuyển đổi như vậy, giải pháp có lẽ nên bao gồm một số tính linh hoạt w.r.t. các loại đang được sử dụng và ngôn ngữ yêu cầu.
Ngay từ đầu, được đưa ra ngày yêu cầu "câu trả lời hợp lý hơn" (khoảng tháng 8 năm 2014) sẽ được áp dụng tự do C++ 11.
Một phiên bản chú thích của mã này, với các loại tương ứng với OP:
std::vector<std::uint8_t> convert(std::string const& src)
{
// error check on the length
if ((src.length() % 2) != 0) {
throw std::invalid_argument("conversion error: input is not even length");
}
auto ishex = [] (decltype(*src.begin()) c) {
return std::isxdigit(c, std::locale()); };
// error check on the data contents
if (!std::all_of(std::begin(src), std::end(src), ishex)) {
throw std::invalid_argument("conversion error: input values are not not all xdigits");
}
// allocate the result, initialised to 0 and size it to the correct length
std::vector<std::uint8_t> result(src.length()/2, 0);
// run the actual conversion
auto str = src.begin(); // track the location in the string
std::for_each(result.begin(), result.end(), [&str](decltype(*result.begin())& element) {
element = static_cast<std::uint8_t>(std::stoul(std::string(str, str + 2), nullptr, 16));
std::advance(str, 2); // next two elements
});
return result;
}
Mẫu phiên bản mã cho biết thêm tính linh hoạt;
template <typename Int /*= std::uint8_t*/,
typename Char = char,
typename Traits = std::char_traits<Char>,
typename Allocate = std::allocator<Char>,
typename Locale = std::locale>
std::vector<Int> basic_convert(std::basic_string<Char, Traits, Allocate> const& src, Locale locale = Locale())
{
using string_type = std::basic_string<Char, Traits, Allocate>;
auto ishex = [&locale] (decltype(*src.begin()) c) {
return std::isxdigit(c, locale); };
if ((src.length() % 2) != 0) {
throw std::invalid_argument("conversion error: input is not even length");
}
if (!std::all_of(std::begin(src), std::end(src), ishex)) {
throw std::invalid_argument("conversion error: input values are not not all xdigits");
}
std::vector<Int> result(src.length()/2, 0);
auto str = std::begin(src);
std::for_each(std::begin(result), std::end(result), [&str](decltype(*std::begin(result))& element) {
element = static_cast<Int>(std::stoul(string_type(str, str + 2), nullptr, 16));
std::advance(str, 2);
});
return result;
}
Các convert()
chức năng sau đó có thể được dựa trên basic_convert()
như sau:
std::vector<std::uint8_t> convert(std::string const& src)
{
return basic_convert<std::uint8_t>(src, std::locale());
}
Live sample.
Hey @Nirav, nó trông giống như một vài câu trả lời dưới đây đã giúp giải quyết vấn đề của bạn. Nếu đó là trường hợp, nó sẽ được tốt đẹp để "chấp nhận" câu trả lời bạn thích nhất (với hộp kiểm bên trái của câu trả lời). Bạn có thể (hoặc sẽ có đủ danh tiếng) [vote up] (http://stackoverflow.com/privileges/vote-up) tất cả các câu trả lời hữu ích. –