I am new to C++, and programming, and I want to write a C++ program to convert a float in hexadecimal with the help of pointers
I've looked on other threads and really tried to get a hold of this but can't seem to figure it out.
Here is what I have done so far:
int main()
{
float number = -12.0
unsigned char *ptr = ((unsigned char*) &number);
for (int i = 0; i < sizeof(float); i++)
{
cout << "Byte " [i] << "is : " << ptr[i] << endl;
}
So with this, i assume I am able to have access to the bytes that compose the float. However, can you suggest any ideas to convert this to hexadecimal. I guess, I have to be able to read the binary behind all this... but I am not really sure how.
Note: I understand how to convert from binary to hexadecimal
iostreams can print numbers in hexadecimal:
int main() {
float number=-1.0;
unsigned char *ptr = ((unsigned char*)&number);
for (int i = 0; i < sizeof(float); i++)
{
cout << "Byte ";
cout << setw(0) << dec << i << "is : ";
cout << setw(2) << setfill('0') << hex << ptr[i] << endl;
}
what you want might be sth like this:
float number=-1.0;
char cz[]="0123456789ABCDEF";
int si=sizeof(float);
char* ptr=(char*)(&number);
for(int i=0;si-i;++i){
std::cout<<cz[((*ptr)&0xf0)>>4]<<cz[(*ptr)&0x0f]<<' ';
++ptr;
}
You have minor bug here cout << "Byte " [i] which is the same as doing:
const char *text = "Byte ";
cout << text[i]
Another minor bug is that ptr[] is char thus cout treats it as a printable character (not a number), using (int)ptr[i] will do. Also you want print i as decimal and ptr[i] as hex, so you have to use std::dec and std::hex
cout << "Byte " << std::dec << i << " is : " << std::hex << (int)ptr[i] << endl;
You may polish it a bit by using std::setw() and std::setfill() from <iomanip>:
#include <iostream>
#include <iomanip>
using std::cout;
using std::endl;
int main()
{
float number = -1.0;
unsigned char *ptr = ((unsigned char*) &number);
cout << std::setfill('0');
for (int i = 0; i < sizeof(float); i++)
{
cout << "Byte "
<< std::dec << std::setw(0) << i << " is : "
<< std::hex << std::setw(2) << (int)ptr[i] << endl;
}
return 0;
}
This will print out:
Byte 0 is : 00
Byte 1 is : 00
Byte 2 is : 80
Byte 3 is : bf
Related
Trying to extract each byte in a short I've created.
While I can print the second (or first) byte, I can't get both.
With my current understanding, this should work. Hoping someone can make it clear to me what the error is here. I'm running this on windows x86, so ILP32 data format.
#include <iostream>
using namespace std;
int main()
{
short i = 0x1123;
short* p = &i;
short* p1 = p;
p1++;
char c = *p;
char c1 = *p1;
cout
<< "Short: " << hex << i << '\n'
<< "p: " << p << '\n'
<< "p1: " << p1 << '\n'
<< "c: " << hex << (unsigned int)c << '\n'
<< "c1: " << hex << (unsigned int)c1 << '\n'
;
return 0;
}
Output:
Short: 1123
p: 0041FB58
p1: 0041FB56
c: 23
c1: ffffffcc
Here is the fix:
#include <iostream>
#include <iomanip>
int main()
{
short i = 0x1123;
short* p = &i;
char* c = reinterpret_cast<char*>( p );
char* c1 = c + 1;
std::cout << "Short: " << std::showbase << std::hex << i << '\n'
<< "p: " << p << '\n'
<< "c: " << +( *c ) << '\n'
<< "c1: " << +( *c1 ) << '\n';
return 0;
}
There is no need for p1. The problem with p1++ is that it adds 2 to the value of p1 and not 1 as you would expect. And that's because p1 is a pointer to short so when you increment it, it progresses by 2 (short is 2 bytes). You need to cast it to a char* so that each time you increment it, it will add 1 to the value.
Also, notice the + operator in +( *c ). Using this operator will make sure that *c won't be printed as a character but instead as its ASCII value or whatever value it has, thus there is no need to cast it to int.
Possible output:
Short: 0x1123
p: 0xb71f3ffd8e
c: 0x23
c1: 0x11
An alternative solution that uses no pointer trix and doesn't care about endianness.
#include <iostream>
int main()
{
short i = 0x1123;
unsigned low = i % 256;
unsigned high = i / 256;
std::cout << std::hex
<< "Short: " << i << '\n'
<< "low: " << low << '\n'
<< "high: " << high << '\n';
return 0;
}
Thank you to rustyx and Pete Becker who answered this. The program is aware that the pointer is for a type short therefore when I try to increment it automatically increments the value by 2. This behaviour can be circumvented by casting the pointer to a char.
#include <iostream>
using namespace std;
int main()
{
short i = 0x1123;
cout
<< "Short: " << hex << i << '\n'
;
char* p = (char*)&i;
char c = *p;
cout
<< "p: " << hex << (unsigned int)p << '\n'
<< "c: " << hex << (unsigned int)c << '\n'
;
char* p1 = p + 1;
char c1 = *p1;
cout
<< "p1: " << hex << (unsigned int)p1 << '\n'
<< "c1: " << hex << (unsigned int)c1 << '\n'
;
return 0;
}
Output:
Short: 1123
p: 54fd54
c: 23
p1: 54fd55
c1: 11
I've looked through all previous version of this topic and none have seemed to help.
I've got a value located in unsigned char called Offset.
When printing this with printf("%02X\n", Offset); It prints out the correct value which is 0x2B.
Though when I try with std::cout << std::hex << Offset << std::endl; It always prints a different value.
I have also tried:
std::cout << std::hex << (unsigned int)Offset << std::endl;
std::cout << std::hex << static_cast<unsigned>(Offset) << std::endl;
Though none have seemed to print out the correct value.
As you defined "Offset" like this unsigned char Offset = 0x2B;, Offset's type now is unsigned char and you cant not print a unsigned char variable as a std::hex.
You must first convert it to the std::hex type then print it.
#include <iostream >
int main() {
unsigned char Offset = 0x2B;
printf("%02X\n", Offset);
std::cout << std::hex << Offset << std::endl;
std::cout << std::hex << (unsigned int)Offset << std::endl;
std::cout << std::hex << static_cast<unsigned>(Offset) << std::endl;
return 0;
}
how can i convert a char* address to int?
in cygwin, i've got the error as follow:
test.cpp:31:80: 错误:从‘char*’到‘int’的转换损失精度 [-fpermissive]
cout << "hex:0x" << setw(8) << left << hex << reinterpret_cast(&pchar[i])
(translate: Error, the conversion from ‘char*’ to ‘int’ will lose precision)
following is my source code:
int main()
{
int num = 0x12345678;
char *pchar = reinterpret_cast<char*>(&num);
if (0x12 == *pchar)
{
cout << "big-end" << endl;
}
else if (0x78 == *pchar)
{
cout << "little-end" << endl;
}
else
{
cout << "wtf" << endl;
}
for (int i = 0; i < 4; ++i)
{
cout << "hex:0x" << setw(8) << left << hex << reinterpret_cast<int>(pchar + i)
<< "val:0x" << hex << static_cast<int>(pchar[i]) << endl;
}
return 1;
}
You can't: the behaviour would be undefined. This is because a char* is unrelated to an int.
In your case why not use %p as the format specifier for the pointer? (Strictly speaking you should convert the argument to a void* or const void*).
cout does this automatically for you:
cout << (void*)(pchar);
int main()
{
char B[76]={0};
ifstream infile;
infile.open("tworecords.dat", ios::binary);
infile.read(reinterpret_cast<char*>(B), sizeof (B));
cout << "Array B in hex" << endl;
for (int i = 0; i < 76; i++)
{
cout << hex << B[i] << " " << endl;;
}
return 0;
}
right now it reads the data correctly, but prints out the values as ASCII symbols. I would like to output the actual hex values in the file.
example:
01
3D
76
D6
etc.
Cast it to integer:
cout << hex << static_cast<int>(B[i]) << " " << endl;
Or alternatively, if you don't want to cast, just add 0:
cout << hex << B[i]+0 << " " << endl;
However you probably also want to make sure that for values below 16, a leading 0 is printed (e.g. for the newline character 0A, not just A):
cout << setfill('0') << setw(2) << hex << B[i]+0 << " " << endl;
You simply cast the number to an integer:
cout << hex << (int)B[i] << " " << endl;
the <iostream> library (actually, all stream libraries) output ascii values for char types.
How to get (correctly and/or readable value of) std::numeric_limits<char>::min()?
cout << std::numeric_limits<char>::min() << endl;
cout << std::numeric_limits<char>::max() << endl;
return
�
// some character that can't be copied here, it looks like a rectangle containing four numbers in it
You just need to convert it to something that when streamed to cout will interpret it as an integer. E.g.
#include <limits>
#include <iostream>
#include <ostream>
int main()
{
int minc = std::numeric_limits<char>::min();
unsigned maxc = std::numeric_limits<char>::max();
std::cout << minc << std::endl;
std::cout << maxc << std::endl;
}
I deliberately use unsigned for std::numeric_limits<char>::max() just in case sizeof(int) == 1 and char is unsigned.
The problem is that the standard streams will output chars as characters and not as integral values. You can force them to do that by casting to an integral type that isn't a character type:
cout << (int)std::numeric_limits<char>::min() << endl;
cout << (int)std::numeric_limits<char>::max() << endl;
Just cast it to an int.
cout << (int)std::numeric_limits<char>::min() << endl;
cout << (int)std::numeric_limits<char>::max() << endl;