I am trying to make a function to read in a value, then convert it to little endian.
I wrote this: - template<typename T>
-
void Read(T& value, std::ifstream& in) {
-
std::vector<unsigned char> bytes(sizeof(T));
-
in.read(reinterpret_cast<char*>(&bytes[0]), sizeof(T));
-
value = 0;
-
-
for(int i = 0; i < sizeof(T); i++) {
-
value |= (bytes[i] << i * 8);
-
}
-
}
But this is only working for int and the compiler won't accept trying to give it a float or double.
Should I scrap the template and just overload it?
24 3410
You can't use the |= operator with double. It only works for integer types.
You may have to use an explicit specialization for double.
I just tried it with a unsigned short & short, it doesn't work correctly for them either? No matter what the value it's meant to be reading in, it output 7543 :3
Does a good old C union help? Something like this: -
union enian {
-
unsigned char b[sizeof(double)];
-
unsigned short s;
-
unsigned int i;
-
unsigned long l;
-
float f;
-
double d;
-
} buffer;
-
Read n bytes in the buffer member, reverse n bytes and fetch one of the other members.
kind regards,
Jos
I've never really used unions before.
@MrPickle
Well, what's keeping you?
kind regards,
Jos
@JosAH
I'm not to sure what they are exactly, a reduced class?
@MrPickle
Yep, a very reduced class, even a reduced struct. All the members of a union start at the same place. So in the example above the buffer member takes the same memory as the double d or the int i. So, e.g., when I change the first four bytes of the buffer I directly change the bytes that make up the int i etc.
The buffer char member is just another 'view' of the int i or double d etc. which is exactly what you want although you may not realize that yet ;-)
kind regards,
Jos
So what that was doing was moving everything along, 4 bytes in memory? How does that change the order of the variables in memory?
What JosAH was saying is that you can have -
union myunion
-
{
-
int i;
-
char bytes[4];
-
} hello;
-
then, you can do something like hello.i = 123;
That assigns the number 123 into the memory occupied by hello.i
However, because you have a union, this memory is also occupied by hello.bytes, which is a character array.
In turn, this means that you can manipulate the elements of hello.bytes array (like say, reverse their order), which will also change hello.i
You won't "change the order of the variables", but by reversing the bytes, you will... well, reverse the bytes.
OH, I see. So whatever happens to bytes, also happens to i?
Can I read directly into bytes then? eg;
in.read(&hello.bytes[0], sizeof(int));
Ahh, yes. I get it, thanks for all the help.
A couple questions, will this method work for std::string. I'm not sure it will, will I just have to read it in char by char until char == '\0'.
Have I done this right, because it's giving me linker errors when I try called Read<int>... or Read<unsigned short>... - template <typename T> union Endian {
-
unsigned char bytes[sizeof(T)];
-
T value;
-
};
-
-
template<typename T> void Read(T& value, std::ifstream& in) {
-
Endian<T> e;
-
in.read((&e.bytes[0]), sizeof(T));
-
-
for(int i = 0; i < sizeof(T); i++) {
-
bytes[i] = bytes[sizeof(T) - i]; //Not sure here, might cause access violation?
-
}
-
-
value = e.value;
-
}
- bytes[i] = bytes[sizeof(T) - i]; //Not sure here, might cause access violation?
-
-
//It might.You mean:
-
-
bytes[i] = bytes[sizeof(T) -1- i];
-
That's the only error I see(it would compile with this error).
So which are the errors?
Can you post them?
@Savage
Better change the loop boundary condition as well because as it is now you haven't done anything except for juggling those bytes back and forth ;-)
kind regards,
Jos
I've fixed the linker bug now. There was an error in the header that it wasn't reporting.
The function I wrote doesn't work though, I don't really get what you was trying to say Jos
It looks like your template is not in the same file as main().
Templates are not like functions. They are patterns the compiler copies and substitutes the type you specify on your code. That means the pattern has to be in the same file as the call.
Ok, thanks. I've fixed it now.
I don't know why it's now working though.
It outputs this:
bytes[0] = }
bytes[1] =
bytes[2] =
bytes[3] =
value = 0
It should equal 123
Change your loop to this: -
for(int i= 0, j= sizeof(T); i < --j; i++) {
-
char t= e.bytes[i];
-
e.bytes[i]= e.bytes[j];
-
e.bytes[j]= t;
-
}
-
kind regards,
Jos
Yey, it's working. Thanks everybody. - template <typename T> union Buffer {
-
unsigned char bytes[sizeof(T)];
-
T value;
-
};
-
-
template<typename T> void Read(T& value, std::ifstream& in) {
-
Buffer<T> e;
-
in.read(reinterpret_cast<char*>(&e.bytes[0]), sizeof(T));
-
-
char t;
-
int j;
-
for(int i = 0; i < sizeof(T); i++) {
-
std::cout << i << " ";
-
j = (sizeof(T)-1)-i;
-
t = e.bytes[i];
-
e.bytes[i] = e.bytes[j];
-
e.bytes[j] = t;
-
}
-
std::cout << "\n";
-
-
value = e.value;
-
}
You want to be careful in your "swap the bytes" loop:
Suppose sizeof(T) is 4, then you have
1. swap byte 0 and byte 3
2. swap byte 1 and byte 2
3. swap byte 2 and byte 1
4. swap byte 3 and byte 0
In effect, step 3 cancels step 2 and step 4 cancels step 1 - so the bytes aren't swapped.
You might want to iterate only until sizeof(T)/2
I'm not sure, but should I check if the machine is little endian? Otherwise it's going to make it big endian, right?
If it's little endian, it's going to make it big endian. If it's big endian, it's going to make it little endian.
This just converts it from one to another, it's up to you to figure out how you want to use it...
The OP might want to look at the htons() and htonl() macros. They convert two and four byte integers to 'network byte' order, i.e. big endian order. Those macros don't do anything if the host machine happens to be a big endian machine.
kind regards,
Jos
Alright, thanks for your help.
Sign in to post your reply or Sign up for a free account.
Similar topics
by: kelvSYC |
last post by:
Are there any endianness concerns in C++, or does the compiler take
care of those details? I ask because I'm not sure if code such as the
following have consistent behavior on all platforms.
...
|
by: Case |
last post by:
#include <string.h>
int i; /* 4-byte == 4-char */
char data = { 0x78, 0x56, 0x34, 0x12 };
int main()
{
memcpy(&i, data, 4);
/*
|
by: T Koster |
last post by:
Hi group,
I'm having some difficulty figuring out the most portable way to read 24
bits from a file. This is related to a Base-64 encoding.
The file is opened in binary mode, and I'm using...
|
by: SSM |
last post by:
Hi,
Does C standard comment about "Endianness" to be used
to store a structure/union variables?
Thanks & Regards,
Mehta
|
by: gamehack |
last post by:
Hi all,
I was thinking today, suppose we have the number
n = 0xAB 0xFF
which is equivalent to 44031 in decimal. In big endian it will be
stored as
10101011 11111111
but in little endian...
|
by: friend.05 |
last post by:
Code to check endianness of machine
|
by: Tomás |
last post by:
Let's say you want to write fully portable code that will be writing files
or sending data, and the data is text encoded using Unicode 16-Bit.
Endianness comes into play. I'm writing code at the...
|
by: jacob navia |
last post by:
Hi
Suppose you have somewhere
#define BOOL int
and somewhere else
typedef BOOL int;
|
by: Indian.croesus |
last post by:
Hi,
If I am right Endianness is CPU related. I do not know if the
question is right in itself but if it is then how does C handle issues
arising out of Endianness.
I understand that if we pass...
|
by: Rahul |
last post by:
Hi Everyone,
I have a program unit which does >and << of an integer which is of
4 bytes length. The logic of shifting and action based on the result,
assumes that the system is big-endian.
...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
| |