好的,我认为处理 ASCII 解码是个坏主意,并不能真正回答问题。
我认为您的代码不起作用,因为 setw() 或 istream::width() 仅在您阅读 std::string 或 char* 时才有效。我猜是here
如何使用标准 c++ iostream 转换器的优点。我想出了使用stringstream 类和string 作为缓冲区的想法。问题是将n 字符读入缓冲区,然后使用stringstream 作为转换器工具。
我不确定这是否是最佳版本。应该不会吧。
代码:
#include <iostream>
#include <sstream>
int main(void){
int c;
std::string buff;
std::stringstream ss_buff;
std::cin.width(2);
std::cin >> buff;
ss_buff << buff;
ss_buff >> std::hex >> c;
std::cout << "read val: " << c << '\n';
}
结果:
luk32@genaker:~/projects/tmp$ ./a.out
0a10
read val: 10
luk32@genaker:~/projects/tmp$ ./a.out
10a2
read val: 16
luk32@genaker:~/projects/tmp$ ./a.out
bv00
read val: 11
luk32@genaker:~/projects/tmp$ ./a.out
bc01
read val: 188
luk32@genaker:~/projects/tmp$ ./a.out
01bc
read val: 1
如您所见,它的抗错能力不是很强。尽管如此,在给定条件下工作,可以扩展成一个循环,最重要的是使用iostream 转换工具,所以你身边没有 ASCII 魔法。不过 C/ASCII 可能会更快。
附言。改良版。使用简单的char[2] 缓冲区并使用非格式化的写入/读取将数据移动到缓冲区中(get/write 而不是operator<</operator>>)。理由很简单。我们不需要任何幻想来移动 2 个字节的数据。但是,我们使用格式化提取器进行转换。为了方便起见,我把它做成了一个循环版本。但这并不是超级简单。我花了整整 40 分钟的时间来弄明白非常重要的台词。没有它们,提取适用于前 2 个字符。
#include <iostream>
#include <sstream>
int main(void){
int c;
char* buff = new char[3];
std::stringstream ss_buff;
std::cout << "read vals: ";
std::string tmp;
while( std::cin.get(buff, 3).gcount() == 2 ){
std::cout << '(' << buff << ") ";
ss_buff.seekp(0); //VERY important lines
ss_buff.seekg(0); //VERY important lines
ss_buff.write(buff, 2);
if( ss_buff.fail() ){ std::cout << "error\n"; break;}
std::cout << ss_buff.str() << ' ';
ss_buff >> std::hex >> c;
std::cout << c << '\n';
}
std::cout << '\n';
delete [] buff;
}
样本输出:
luk32@genaker:~/projects/tmp$ ./a.out
read vals: 0aabffc
(0a) 0a 10
(ab) ab 171
(ff) ff 255
请注意,c 未按预期读取。
我在这里找到了所需的一切http://www.cplusplus.com/reference/iostream/