c++ stringstream read 似乎没有读取整个缓冲区

问题描述 投票:0回答:2

我有以下代码:https://godbolt.org/z/9aqqe5eYh

#include<string>
#include<sstream>
#include<iomanip>
#include<iostream>

int main() {
  std::string line = "fa0834dd";

  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() << " ";
    ss >> byte;
    std::cout << std::hex << std::setw(2) << byte << std::endl;
  }
}
理想情况下,这会接收一串十六进制数字,将它们拆分为字节(一对十六进制数字)并将其存储为字节(出于说明目的,我仅使用上面的一个

std::uint8_t

)。
上面的代码输出如下:

Program returned: 0 Program stdout fa f 08 0 34 3 dd d
这看起来有点奇怪。一个 

std::uint8_t

 应足以存储 2 个十六进制字符的数据。但似乎 
ss >> byte
 只存储前面的十六进制字符。我的猜测是:

ss << std::hex << line.substr(i, 2);
实际上将每个十六进制字符存储为 1 个字节?

如何修复上述代码以生成等于字符串中 2 个十六进制字符的单字节值?

c++ string stringstream
2个回答
3
投票

stringstream

 不符合将字符表示解析为字节值的条件。

您可以使用类似

strtol

之类的东西来将字符串实际解析为值。

#include<string> #include<sstream> #include<iomanip> #include<iostream> #include<cstdint> int main() { std::string line = "fa0834dd"; 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<int>(byte) << std::endl; } }

参考帖子


3
投票
问题是

std::hex

仅适用于整数输入/输出,虽然
uint8_t
在技术上是一个整数,但它只是下面的一个
unsigned char
iostream
将输入和输出其字符值而不是其整数值。换句话说,您的循环将两个字符放入 
stringstream
 中,然后再次提取第一个字符。

如果要将十六进制数据转换为原生整数类型,可以使用

std::stoi 或类似的函数。例如(仅提取第一个字节):

std::string hexdata = "01020304"; size_t length; // attempt to convert just the first two characters uint8_t firstbyte = std::stoi(hexdata.substr(0, 2), &length, 16); // "length" is set to the number of characters successfully parsed // so if it is not the same number of characters that you supplied, // then there's an issue. In this case, we are expected 2. if (length != 2) { std::cerr << "was that hex??" << std::endl; } else { // you'll need to cast it to an integer type in order to see its integer value // otherwise iostreams will just output the character value std::cout << "value of byte is " << static_cast<int>(firstbyte) << std::end; }
如果根本不可能进行转换(例如,提供的字符串中没有一个字符是可转换的),

std::stoi

也可能会抛出异常。

© www.soinside.com 2019 - 2024. All rights reserved.