快速将原始数据转换为十六进制字符串在C++中。

13
我正在从文件中读取数据,并尝试将原始数据显示为两位十六进制字符串。
我使用的是Qt框架,特别是QTextEdit。
我尝试了许多不同的方法,并且几乎实现了我想要的功能,但是它有一些意外的错误,我对此一无所知。
目前这是我的实现:
1)读取数据:
ifstream file (filePath, ios::in|ios::binary|ios::ate);
if (file.is_open())
{
    size = file.tellg();
    memblock = new char [size+1];
    file.seekg(0, ios::beg);
    file.read(memblock, size);
    file.close();
}

2) 创建一个将被使用的单个QString(因为QTextEdit需要一个QString):

QString s;

3) 循环遍历数组,将每个连续的字符附加到 QString s 中。

int count = 0;
for(i=0;i<size;i++)
{
    count++;;
    s.append(QString::number(memblock[i], 16).toUpper());
    s.append("\t");
    if (count == 16)
    {
        s.append("\n");
        count -= 16;
    }
}

现在这个程序运行得很好,但是当它遇到一个字符FF时,它会显示为FFFFFFFFFFFFFFFF

所以我的主要问题是:

  1. 为什么只有'FF'字符会显示为'FFFFFFFFFFFFFFFF'?
  2. 有没有一种方法可以将char数据转换为十六进制字符串而不使用QString::number?

我希望这个实现尽可能快,所以如果类似sprintf的东西能够工作,请告诉我,因为我猜想那可能比QString::number更快。


1
为什么不直接使用C++本身而非QString呢?你可以在C++中完成,然后将其放入QString中。 - John
这样看起来会更快,谢谢。 - krb686
2个回答

22

QString 不能用于二进制数据,你应该使用 QByteArray。它可以很容易地从 char* 缓冲区创建,并且可以使用 toHex 转换为十六进制字符串。

QByteArray array(memblock, size);
textEdit->setText(QString(array.toHex()));

1
好的,这似乎是最好的答案。我不知道QByteArray甚至存在,它似乎更适合这种情况。现在,如果我想将其他字符附加到QString中,例如在每个2位十六进制值之间添加'\t',并在16个值后添加'\n'怎么办?看起来我可以使用QString.append(QByteArray),但不能使用QString.append(QByteArray[i])。有什么帮助吗? - krb686
1
在获得十六进制表示后,最好使用QString进行操作。因此,您可以使用QString s = array.toHex();。现在,您可以使用QString :: insert直接将字符插入字符串中(但要仔细计算插入索引),或者您可以使用midRef提取原始字符串的部分,并使用append将它们附加到新字符串中。 - Pavel Strakhov
非常好,我不知道那个。相比循环和使用QString.append(array.at()),你认为有什么优点?会更快吗? - krb686
复制2个数字,需要使用array.at(和append)进行2次调用或使用1次midRef(和append)进行1次调用。因此,我猜使用midRef会稍微更快一些。 - Pavel Strakhov

3

QString::number没有重载函数接受char类型的参数,因此你的输入被提升为int类型;因此,你将看到符号扩展的效果。对于任何大于0x7F的输入,您应该看到类似的行为。

在调用函数之前尝试将数据进行转换。

s.append(QString::number(static_cast<unsigned char>(memblock[i]), 16).toUpper());

逐个放置字符非常缓慢。QString可以从char*缓冲区转换。但是QString不能包含二进制数据。 - Pavel Strakhov
@Riateche 嗯,他并没有将二进制数据放入QString中,而是将字节转换为它们的十六进制表示(字符串),然后将其附加。但我同意你的QByteArray方法更好;我只是试图回答他的问题。 - Praetorian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接