[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

Reading Hex values - how to use 'Unsigned Byte' value instead of signed byte value

Posted on 2003-10-21
11
Medium Priority
?
500 Views
Last Modified: 2010-04-01
Hi there, ive got some code which reads 4 bytes of the Hex values of a file (specified by a command line argument), and prints them out. For some reason, when I read in a value which has a negative signed byte value, the program outputs a small number of F's before displaying the actual hex value. Could anyone help me on this one? The code is here:

---------------------------------------
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <string>
#include <iomanip>

#define NO_BYTES 4

char readbuffer[NO_BYTES];
int no_files;
int i;

using namespace std;

int main(int argc, char *argv[])
{
  ifstream InFile;
  InFile.open(argv[1], ios::in | ios::binary);  

  //print filename to file
  printf("File Name: ");
  printf(argv[1]); //print first argument (filename)
 
  //print filesize to file
  InFile.getline(readbuffer, NO_BYTES+1);
  cout << endl << "Header: ";
 
  //print hex values  
  while (i<NO_BYTES)
  {
  printf("%02X",readbuffer[i]);
  i++;
  }
  cout << endl;
   
  system("PAUSE");      
  return 0;
}
-------------------------------
0
Comment
Question by:LiamV
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 3
11 Comments
 
LVL 16

Expert Comment

by:imladris
ID: 9592776
The value for -2 in hex in 4 bytes is 0xfffffffe. So one would expect to print those f's with a %0X format specifier. What do you expect it to print?
0
 
LVL 8

Expert Comment

by:Exceter
ID: 9594247
>> char readbuffer[NO_BYTES];

should probably be,

unsigned char readbuffer[NO_BYTES];

because you then have a sign biy for every byte in the 4 byte sequence.

Exceter
0
 
LVL 8

Expert Comment

by:Exceter
ID: 9594286
It seems apparent that your input file does not contain these values as hex text or you would simly display the contents of the array. Therefore, if it is binary, I think you should be using read instead of getline. For example,

InFile.read((char*)readbuffer, NO_BYTES);

You don't need to null terminate the array unless youplan to use this array in functions that depend on this. Since the array contains binary data, this isn't very likely but I thought I'd mention it anyway.

Exceter
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:LiamV
ID: 9597133
thankyou, but neither works, using an unsigned char with getline or read gives an invalid converstion error (unsigned char* -> char *). Basicly if the input file has the hex string 01D7, the program will output the 01 byte, then will output 'FFFFFFD7000' for the second byte, instead of just 'D7' which i want.
0
 
LVL 8

Expert Comment

by:Exceter
ID: 9598188
>> Basicly if the input file has the hex string 01D7

If the input file contains a hex string, then you don't need to do any conversions at all. For example,

std::string number;
ifstream in( argv[1], ios::in );

in >> number;
cout << number << endl;

in.close();

-- input file --
01D7
-- eof--

-- output --
01D7

Exceter
0
 

Author Comment

by:LiamV
ID: 9599375
The hex values are not in a text file. They are in a binary file and i need to get the hex values for the bytes.
0
 
LVL 16

Accepted Solution

by:
imladris earned 280 total points
ID: 9599424
If the input file is not a string (it's not clear from your remark), but contains two hex bytes 0x01 and 0xd7, then you could resolve it by casting the char and masking. The %0X format specifier, you see, expects an integer, and it expects an integer to be 4 bytes. So if you cast the array element to an integer, and mask off any leading f's you should get what you want:

  printf("%02X",((int)readbuffer[i])&0x0ff);

0
 
LVL 16

Expert Comment

by:imladris
ID: 9599435
Cross posted there. So, the casting should help then.
0
 
LVL 8

Assisted Solution

by:Exceter
Exceter earned 120 total points
ID: 9599659
>> The hex values are not in a text file. They are in a binary file

Thanks for the clarification. Your remarks were confusing because hex is a numbering system. Since, to the computer, everything is binary a hex number MUST be text. Any way you display it the number is still stored in binary. The only difference is the way you choose to display it. For example,

FF == 255 == 11111111

all represent the same number. This can be proved with the equation,

decimal_value = digit_value * radix ^ place_value

Therefore, FF translates to decimal as follows,

15 = 15 * 16^0
245 = 15 * 16^1
245 + 15 = 255

11111111 translates to decimal as follows,
1 = 1 * 2^0
2 = 1 * 16^1
4 = 1 * 16^2
8 = 1 * 16^3
16 = 1 * 16^4
32 = 1 * 16^5
64 = 1 * 16^6
128 = 1 * 16^7

1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 = 255

Therefore,

255 == 255 == 255

and you can plainly see that each of these represent the same value. However, the computer can only store this value as 11111111. It is slightly ambigous to say that the file is binary and that it contains a hex string. This implies a text file containing an actual string consisting of characters and not the binary value that they represent.

You can read four bytes from file and display them in hex as follows(assuming 32 bit architecture),

unsigned int number;
InFile.read((char*)&number, NO_BYTES);
cout << hex << number << endl;

Cheers!
Exceter
0
 

Author Comment

by:LiamV
ID: 9607081
Thankyou both for the comments. imladris, your code worked fine and removed all those FF's from the output. Exceter im sorry but your code seems to take bytes from further on in the steam and output them in a peculiar order.
0
 
LVL 8

Expert Comment

by:Exceter
ID: 9607962
>> Thankyou both for the comments.

You are most welcome.

>> Exceter im sorry but your code seems to take bytes from further on in the steam...

It would if you only read in two bytes.

>> ...and output them in a peculiar order.

That sounds like an endian issue. In Big Endian binary numbers are stored with the high order bytes on the left while Little Endian stores the high order bytes on the right. For example, in Big Endian, the following value would be written to disk as,

Value: 00FF23AB
Written: 00FF23AB

In little Endian it would be written as,

Value: 00FF23AB
Written: AB23FF00

Cheers!
Exceter
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

656 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question