我有以下代碼。https://godbolt.org/z/9aqqe5eYh
#include<string>
#include<sstream>
#include<iomanip>
#include<iostream>
int main() {
std::string line = "fa0834dd"/span>;
for(int i = 0; i < line.length(); i = 2) {
std::stringstream ss;
std::uint8_t byte;
ss << std::hex << line.substr(i, 2)。
std::cout << ss.str() << " "/span>;
ss >> byte;
std::cout << std::hex << std::setw(2) << byte << std::endl。
}
實際上,這是在接收一串十六進制數字,將其分割成位元組(一對十六進制數字)并存盤到位元組中(為了說明問題,我在上面只使用一個std::uint8_t)。
上述代碼的輸出是這樣的:
程式回傳。0。
程式stdout
fa f
08 0 程式 stdout fa f
343
dd d
這似乎有點奇怪。一個std::uint8_t應該足以存盤2個十六進制字符的資料。但似乎ss >> byte只能存盤前面的十六進制字符。我的猜測是:
ss << std::hex << line.substr(i, 2)。
實際上是將每個十六進制字符存盤為1個位元組?
我如何修正上述代碼,以生成一個等于字串中2個十六進制字符的單位元組值?
uj5u.com熱心網友回復:
stringstream不符合決議字符表示為位元組值的條件。
你可以使用類似strtol的東西來實際決議字串為值。
#include<string>/span>
#include<sstream>
#include<iomanip>
#include<iostream>
int main() {
std::string line = "fa0834dd"/span>;
for(int i = 0; i < line.length(); i = 2) {
std::string ss = line.substr(i,2)。
std::cout << ss << ";
std::uint8_t byte = static_cast<std::uint8_t> (strtol(ss. c_str(), NULL, 16)。
std::cout << std::hex << static_cast(byte) < < std::endl;
}
uj5u.com熱心網友回復:
問題是,std::hex只適用于整數的輸入/輸出,雖然uint8_t在技術上是一個整數,但它只是一個unsigned char下,iostream將輸入和輸出其字符值,而不是其整數值。換句話說,你的回圈將兩個字符放入stringstream,然后將第一個字符再次提取出來。
如果你想將十六進制資料轉換為本地整數型別,你可以使用std::stoi或類似的函式。例如(只提取第一個位元組):
std::string hexdata = "01020304"/span>。
size_t length;
//嘗試只轉換前兩個字符。
uint8_t firstbyte = std::stoi(hexdata. substr(0, 2), &length, 16) 。
// "length "被設定為成功決議的字符數。
//所以如果它與你提供的字符數不一樣,。
//那么就有問題了。在這種情況下,我們希望是2.。
if (length != 2)
{
std::cerr << "那是十六進制嗎?" << std::endl;
}
else else ?
{
// you'll need to cast it to an integer type in order to see its integer value.
//否則iostreams將只輸出字符值。
std::cout << "byte的值是" << static_cast<int>(firstbyte) << std::end;
}
std::stoi如果完全沒有轉換的可能(例如,提供的字串中沒有一個字符可以轉換),也可能拋出一個例外。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/324476.html
標籤:
