13

I'm reading data from a file and trying to display the raw data as 2 digit hex strings.

I'm using the Qt framework, specifically the QTextEdit.

I've tried a bunch of different approaches and have almost accomplished what I want it to do, however it has some unexpected errors I don't know anything about.

Currently this is my implementation:

1) Read in the data:

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) Create a single QString that will be used (because QTextEdit requires a QString):

QString s;

3) Loop through the array appending each successive character to the 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;
    }
}

Now this works fine, except when it reaches a character FF, it appears as FFFFFFFFFFFFFFFF

So my main questions are:

  1. Why do only the 'FF' characters appear as 'FFFFFFFFFFFFFFFF' instead?
  2. Is there a way to convert the char data to base 16 strings without using QString::number?

I want this implementation to be as fast as possible, so if something like sprintf could work, please let me know, as I would guess that might be faster that QString::number.

krb686
  • 1,726
  • 9
  • 26
  • 46
  • 1
    Why not do this natively in C++ rather than using QString? http://stackoverflow.com/questions/10599068/how-do-i-print-bytes-as-hexadecimal You can do it in C++ then just shove it in a QString? – John Jun 20 '13 at 17:28
  • This also looks like it would be much faster, thanks. – krb686 Jun 20 '13 at 17:43

2 Answers2

22

QString can't be used for binary data. You should use QByteArray instead. It can be easily created from char* buffer and can be easily converted to hex string using toHex.

QByteArray array(memblock, size);
textEdit->setText(QString(array.toHex()));
Pavel Strakhov
  • 39,123
  • 5
  • 88
  • 127
  • 1
    Okay this seems to be the best answer. I didn't know QByteArray even existed and it seems like it's much more suited for this kind of thing. Now what if I want to append other characters to the QString, like '\t' in between each 2-digit hex value, and '\n' after 16 of them? It looks like I can do QString.append(QByteArray), but not QString.append(QByteArray[i]). Any help? – krb686 Jun 20 '13 at 17:41
  • 1
    After you have hex representation, it's better to work with it using QString. So you have `QString s = array.toHex();`. Now you can use `QString::insert` to insert characters into string directly (but calculate inserting index carefully), or you can extract parts of original string using `midRef` and append them into new string using `append`. – Pavel Strakhov Jun 20 '13 at 17:52
  • Very nice I didn't know about that. What would you say the advantages are as opposed to looping and doing QString.append(array.at())? Would it be any faster? – krb686 Jun 20 '13 at 17:58
  • To copy 2 digits you need 2 calls of `array.at` (and `append`) or 1 call of `midRef` (and `append`). So I guess using `midRef` will be slightly faster. – Pavel Strakhov Jun 20 '13 at 18:06
3

QString::number doesn't have an overload that takes a char, so your input is being promoted to an int; consequently you're seeing the effects of sign extension. You should be seeing similar behavior for any input greater than 0x7F.

Try casting the data prior to calling the function.

s.append(QString::number(static_cast<unsigned char>(memblock[i]), 16).toUpper());
Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • Putting one char at a time is very slow. QString can be converted from `char*` buffer. But QString can't contain binary data. – Pavel Strakhov Jun 20 '13 at 17:35
  • @Riateche Umm, he's not putting binary data into the QString, he's converting the bytes to their hex representations (strings), and appending that. But I agree that your QByteArray method is better; I only attempted to answer his question. – Praetorian Jun 20 '13 at 17:38