我有一个简单的文本文件,我想把它读成十六进制。例如,以下文本在文本文件“315c4e”中,现在这些实际上是三个字节,我想将它们保存在单独的变量中(或者在数组中,这是可能的)。例如,第一个变量如uint8_t v1,应该包含31,换句话说,这个变量应该有00110001值(十六进制为31)。
我正在大学里做加密工作,我不得不从包含十六进制编码密文的文本文件中读取值。
答案 0 :(得分:1)
普通setw
和setprecision
不会将读取的输入数量限制为两个字符,所以像这样:
infile >> std::setw(2) >> setprecision(2) >> std::hex >> ch;
......就行不通。在这种情况下,它可能就像读取2个字符的字符串一样简单,并自己进行转换:
#include <iostream>
#include <iomanip>
#include <sstream>
#include <vector>
#include <ctype.h>
unsigned char hstouc(std::string const &in) {
static const std::string v{ "0123456789ABCDEF" };
return v.find(toupper(in[0])) * 16 + v.find(toupper(in[1]));
}
int main() {
std::istringstream in{ "315c4e" };
std::vector<unsigned char> vals;
std::string temp;
while (in >> std::setw(2) >> temp)
vals.push_back(hstouc(temp));
for (unsigned v : vals)
std::cout << v << "\t";
}
如果您的输入是机器生成的,那可能就足够了。如果它可能是手动编辑(或任何其他可能产生错误输入的东西),您可能需要/想要在转换例程中添加一些错误检查。或者,您可能希望使用已经执行此类检查的strtoul
之类的内容,然后将结果转换为unsigned char
。
答案 1 :(得分:0)
这个问题给了我以下功能的想法,我无法抗拒在这里发布。顺便说一下,有一个标准函数与此atob
做同样的事情吗?
int atob(unsigned char c) {
static char x[256];
int i;
if (x[0]==0) {
for(i=0;i<256;i++) x[i] = -1;
for(i=0;i<10;i++) x[i+'0'] = i;
for(i=0;i<6;i++) x[i+'a']= x[i+'A'] = i+10;
}
return(x[c]);
}
int main() {
FILE *ff;
int hex, c1, c2;
ff = fopen("test.txt", "r");
for(;;) {
c1 = fgetc(ff);
c2 = fgetc(ff);
if (c2 == EOF) break;
hex = atob(c1)*16 + atob(c2);
printf("0x%02x ", hex);
}
fclose(ff);
}
答案 2 :(得分:0)
如果要读取由空格分隔的3个字节(6个字符)的元组:
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <vector>
struct ToHex
{
typedef std::uint8_t byte;
typedef std::istream::traits_type traits;
byte& value;
ToHex(byte& value)
: value(value)
{}
void read(std::istream& stream) const {
byte b[2];
for(unsigned i = 0; i < 2; ++i) {
traits::char_type ch = stream.get();
if('0' <= ch && ch <= '9') b[i] = ch - '0';
else if('a' <= ch && ch <= 'f') b[i] = ch - 'a' + 10;
else if('A' <= ch && ch <= 'F') b[i] = ch - 'A' + 10;
else {
if(ch != traits::eof())
stream.putback(ch);
stream.setstate(std::ios_base::failbit);
}
}
value = b[0] * 16 + b[1]; // Rubbish if an extraction failed
}
};
inline ToHex to_hex(ToHex::byte& value) {
return ToHex(value);
}
inline std::istream& operator >> (std::istream& stream, const ToHex& value) {
value.read(stream);
return stream;
}
int main() {
std::istringstream input(""
"315c4e\n"
"010c0e\n"
"Failure");
ToHex::byte a[3];
input >> std::ws;
while(input && ! input.eof()) {
for(unsigned i = 0; i < 3; ++i) {
input >> to_hex(a[i]);
}
if(input) {
for(unsigned i = 0; i < 3; ++i)
std::cout << std::hex << std::setw(2) << std::setfill('0') << (unsigned)a[i];
std::cout << '\n';
input >> std::ws;
}
}
if(input.fail()) {
std::cerr << "Failure\n";
}
}