Hi all.
How can I translate an int into a char* ? mmmh, not 2 gives "2", but in fact to chage a data type ? I mean, to store an int (or a long, double and so on), under the form a a char[]
and, how to change a char[] into an int or a long and so on...
http://www.cplusplus.com/ref/cstdlib/
Look for the functions atoi and itoa, those are for regular char's.
mmh, thanks, but it wasn't what I was looking for.
I don't want these functions to change any bit
see this:
| Code: |
int value = 35;
char translated[sizeof(int)];
translated = some_cast(value);
// translated will be precisely identical to value, but with type char, and won't be "35"
value = 0;
value = some_cast(translated);
cout << value << endl; // has to output 35
|
Do you see what I mean ? It has to work with every kind of data...[/code]
sizeof gets the "size" of an int doesn't it, so what do you need that for?
a char is one byte long.
I need a char arry of sizeof(int) bytes long to store an int.
| Antoine_935 wrote: |
a char is one byte long.
I need a char arry of sizeof(int) bytes long to store an int. |
An int is two bytes long.
I don't think you need a char[] with the length = sizeof(int). That's because an int and char[] is something different. Your array needs to be as long as the number of numbers there's in your number. Can't you just use itoa? That's specially made for those kind of things
.
| Nyizsa wrote: |
| Antoine_935 wrote: | a char is one byte long.
I need a char arry of sizeof(int) bytes long to store an int. |
An int is two bytes long. |
this is system dependent. On my SlackWare, int length is 4 bytes.
What OS do you use ?
| Gleter wrote: |
| I don't think you need a char[] with the length = sizeof(int). That's because an int and char[] is something different. Your array needs to be as long as the number of numbers there's in your number. Can't you just use itoa? That's specially made for those kind of things . |
I don't want this...
this is (maybe) my int:
10011001 10001111 00101101 00111011
the char has to be
10011001 10001111 00101101 00111011
and nothing else
| Antoine_935 wrote: |
| Nyizsa wrote: | | Antoine_935 wrote: | a char is one byte long.
I need a char arry of sizeof(int) bytes long to store an int. |
An int is two bytes long. |
this is system dependent. On my SlackWare, int length is 4 bytes.
that's why I put sizeof(int), this allows to get a more portable code, which is very important for my project.
What OS do you use ?
| Gleter wrote: | | I don't think you need a char[] with the length = sizeof(int). That's because an int and char[] is something different. Your array needs to be as long as the number of numbers there's in your number. Can't you just use itoa? That's specially made for those kind of things . |
I don't want this...
this is (maybe) my int:
10011001 10001111 00101101 00111011
the char has to be
10011001 10001111 00101101 00111011
and nothing else |
| Antoine_935 wrote: |
| Nyizsa wrote: | | Antoine_935 wrote: | a char is one byte long.
I need a char arry of sizeof(int) bytes long to store an int. |
An int is two bytes long. |
this is system dependent. On my SlackWare, int length is 4 bytes.
What OS do you use ? |
You were right - it is 4 bytes long. I was deceived because the book says int goes from -32767 to 32767. And this interval needs only two bytes.
(I am using Debian anyway.)
That was what I thought too
but an int of bytes goes much further...
I think short is 2 bytes long, I'm gonna check it right now.
And why have I posted my own poste quoted ??? Dono understand, maybe it's because of Opera at reloading...
EDIT: sizes :
Size of short: 2
Size of int: 4
Size of long: 4
Size of float: 4
Size of double: 8
?? int and longs are both 4 bytes long ???
here's the code if you want to test it on your computer:
| Code: |
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
cout << "Size of short: " << sizeof(short) << endl;
cout << "Size of int: " << sizeof(int) << endl;
cout << "Size of long: " << sizeof(long) << endl;
cout << "Size of float: " << sizeof(float) << endl;
cout << "Size of double: " << sizeof(double) << endl;
} |
This is cpp code 
| Antoine_935 wrote: |
| Nyizsa wrote: | | Antoine_935 wrote: | a char is one byte long.
I need a char arry of sizeof(int) bytes long to store an int. |
An int is two bytes long. |
this is system dependent. On my SlackWare, int length is 4 bytes.
What OS do you use ?
| Gleter wrote: | | I don't think you need a char[] with the length = sizeof(int). That's because an int and char[] is something different. Your array needs to be as long as the number of numbers there's in your number. Can't you just use itoa? That's specially made for those kind of things . |
I don't want this...
this is (maybe) my int:
10011001 10001111 00101101 00111011
the char has to be
10011001 10001111 00101101 00111011
and nothing else |
For that purpose itoa() is written I think. Just check it out. I've used it successfully before and it worked.
It can be that int, long and float are the same size, that's compiler-specific. The minimum sizes of types is specified by the ANSI standard. But it's possible. 
No, it doesn't do what I want.
| Code: |
int len = 50;
char *translated = itoa(len); // translated will be "50\0", and thus a different bit-a-bit representation
|
| Antoine_935 wrote: |
No, it doesn't do what I want.
| Code: |
int len = 50;
char *translated = itoa(len); // translated will be "50\0", and thus a different bit-a-bit representation
|
|
Why do you mind the null-terminated string? Most strings are null-terminated I think? That null-character is there to make clear to certain functions (almost all functions) that the end of a string is reached.
What are you actually trying to program?
| Gieter wrote: |
Why do you mind the null-terminated string? Most strings are null-terminated I think?
==> Yes, and so what ?
What are you actually trying to program?
A way to store every kind of variable into a char* |
| Antoine_935 wrote: |
| A way to store every kind of variable into a char* |
Well... good one. But I think there is some sense in that we have different variables...
Why are you trying to store integer values as a char datatype anyway? It may help us to help you if we understood why.
| Antoine_935 wrote: |
| Gieter wrote: | Why do you mind the null-terminated string? Most strings are null-terminated I think?
==> Yes, and so what ?
What are you actually trying to program?
A way to store every kind of variable into a char* |
|
Almost all strings are null-terminated strings, so why do you want a non-null-terminated string? 99% of the programs work fine with null-terminated string, if you output that string, you don't notice that trailing character.
http://www.cplusplus.com/doc/tutorial/ntcs.html : about (null-terminated) strings.
What is the precise goal of the program? That way we'll know why you don't want a null-terminated string and we'll be better able to help you.
| AftershockVibe wrote: |
| Why are you trying to store integer values as a char datatype anyway? It may help us to help you if we understood why. |
Because I have to store every kind of values in a vector, without taking too much place, and thus converting these vars into char*
I don't care about null-terminated strings and other things, I just want to translate every kinds of variables into char*
A vector is the same as an array right? The problem your having is that you're working against the programming language - it doesn't want to let you store one datatype as another as usually it's a recipe for disaster.
Another added problem is that you are trying to store all your values into one byte (as a char is one byte). This is a problem as you will only have 2^8 = 256 possible combinations so the maximum integer value you could ever store is 255. Doubles are pretty much impossible to store unless you define yourself a very restrictive data type.
If you really want to go about things this way you are going to have to define your own data type with its own methods for conversion, which will invlove manipulating things down at the bit level.
Also, why do you need to store mixed data types in the same array anyway?
| AftershockVibe wrote: |
| Another added problem is that you are trying to store all your values into one byte (as a char is one byte). |
That's why I need to translate them into char*, which are chars arrays... to have more than one byte space.
| Antoine_935 wrote: |
| AftershockVibe wrote: | | Another added problem is that you are trying to store all your values into one byte (as a char is one byte). |
That's why I need to translate them into char*, which are chars arrays... to have more than one byte space. |
But a char array is just a string! That's why itoa() was mentioned before... I'm afriad I don't really understand what you're trying to do.
itoa does not respect the byte representation of a variable.
Consider
| Code: |
struct a_structure {
int the_int = 0;
char * the_char = "";
}
|
This kind of variable, as EVERY kind of variable, should be turned into a char*, with the same byte representation:
int = 50 and char* = "50"; does not have the same byte-to-byte representation, I DON'T NEED itoa function !
You can get answer for this question on http://www.cplusplus.com
other recommended books are "How to Programme" by Dietel and Dietel
and "Object Oriented Programming" by Robert Lafore.
I hope you will foind this recommendations helpful.
With regards,
| Antoine_935 wrote: |
Consider
| Code: |
struct a_structure {
int the_int = 0;
char * the_char = "";
}
|
|
Antoine, ignore these people. They don't understand you. You're half way there already. Try using a union instead of a struct.
| Code: |
union a_structure {
int the_int = 0;
char * the_char = "";
}
|
Then, the int and the char* are stored in the same bit of memory, so if you store '23' in a_structure.the_int, the_char will automatically contain a char* representation of that same bit-pattern.
Another, arguably better solution, is reinterpret_cast<>.
| Code: |
typedef char[sizeof(int)] charint;
char[sizeof(int)] x;
int y;
// lets you do
y = reinterpret_cast<int>(x);
// and
x = reinterpret_cast<charint>(x);
|
It achieves exactly what you're looking for, and the explicit cast means you can find in the code the places where you made the cast, whereas a union kind of hides what you're doing from anyone reading the code, and also from the compiler.
The question is a not specific enough. To transform a string to numbers or a number, you need a packing algorithm like huffman stuff. This subject can get very complicated….
| mogyoro wrote: |
| The question is a not specific enough. |
I don't think you understood the question, which I think was quite specific and straightforward: how to change the datatype of an int variable to char*. I could be wrong, though. Only Antoine_935 can tell us which of us is right.
What you want is this:
| Code: |
int new_number;
cout << "Insert a number\n";
cin >> new_number;
char char_int[2];
char low_part;
char high_part;
low_part = new_number;
high_part = new_number>>8;
char_int[0] = low_part;
char_int[1] = high_part;
|
To extract the value:
| Code: |
int getValue( char char_int )
{
int low_part;
int high_part;
low_part = (int)char_int[0];
high_part = (int)char_int[1];
return ((high_part*256)+low_part);
}
|
you mean something like this?
| Code: |
int iVar;
char * pcVar = (char *)&iVar;
// &iVar - get address of integer variable
// (char *) - change the type of address from (int *) to (char *)
iVar = 0x04030201;
// after this
// pcVar[0] == 1
// pcVar[1] == 2
// pcVar[2] == 3
// pcVar[3] == 4
pcVar[0] = 0x78;
// after this
// iVar == 0x04030278;
|
But it works only on Intel compatible processors, if you do this on some other (PowerPC, Motorola, ...) you will get reverse order. So be careful with this.
You know... not only have a lot of the suggestions in this thread been very bad so far (it would take far too long to pick apart all of the bad ideas and misconceptions that have popped up so far)... the original idea itself was not the greatest. What is the motivation for doing this? Are you sure that it can't be done better/smarter/faster?
Hello,
I realize that this thread is now over two years old but.. anyways ^^ I thought I'd share a little.
I once wanted to do something similar to get some understanding how the bytes were organized
Anyhow I did it like JayBee, casting the adress of the int to a char pointer, to read the bytes individually.
And if you want to store the content of an int bytewise in a char[] you could just do a memcpy() maybe?
Something like..
| Code: |
int nr = 56709283;
unsigned char data[4];
memcpy(&data, &nr, 4);
|
| xtoffer wrote: |
Hello,
I realize that this thread is now over two years old but.. anyways ^^ I thought I'd share a little.
I once wanted to do something similar to get some understanding how the bytes were organized Anyhow I did it like JayBee, casting the adress of the int to a char pointer, to read the bytes individually.
And if you want to store the content of an int bytewise in a char[] you could just do a memcpy() maybe?
Something like..
| Code: |
int nr = 56709283;
unsigned char data[4];
memcpy(&data, &nr, 4);
|
|
C++ is a very powerful and flexible language, by design. It is intended so that whenever anyone asks: "How do i do X in C++?", there will always be an answer, no matter what X is. This is a good thing, because it means that if you should ever really have a need to do what you're describing, you can (in a number of different ways, too).
But it is also a bad thing, because it means that beginners often can't see the forest for the trees. It is rare, rare, RARE to ever have to deal with raw bits and bytes in memory like that. Yes, you can if you have to. But 999,999 times out of a million, you don't really have to, and you're just making your life more difficult.
Yes, if you care about the byte order of an int, that method is a fairly good way to go about finding it out, more or less. (If i were you, i wouldn't hard code the 4, i would use sizeof(int).) The problems with this are:
- You shouldn't have to care about the byte order.
- Even once you know what the byte order is, you still don't necessarily know how the device stores numbers.
- You can't be sure that the structure of the char array is what you think it is.
- Raw memory data is almost always useless in any other context.
Now, some of these may leave you scratching your head, because they're so contrary to the (bad) teaching out there about C++. But here's why:
Point 1: As long as numbers are being treated like numbers (which, logically, they should be), you don't need to care what the format of those numbers is. You also don't even need to care about whether or not they're even in memory at all (they may exist only in registers). The only time this ever comes up is in converting from numbers to something else, or transferring your numbers from one computer to another (over a network, for example, or even into a file format designed to be portable). In both cases, you're talking about the difference between this: | Code: |
unsigned number;
char data[sizeof(unsigned)];
memcpy(data, number);
#if BIG_ENDIAN
big_endian_to_little_endian(data);
#endif
void big_endian_to_little_endian(char data[4])
{
swap(data[0], data[3]);
swap(data[1], data[2]);
} |
And this: | Code: |
unsigned number;
char data[sizeof(unsigned)];
for (int i = 0; i < sizeof(unsigned); ++i)
data[i] = (number >> (8 * i)) & 0xFF; |
Point 2: Endianness is not the only factor in figuring out how a device stores numbers. A four byte number could be stored as 1234 or 4321... or it could also be 2143 or 3412 - and yes, both of those patterns really have existed. Not to mention that you also need to determine whether it's using two's complement or one's complement or signed magnitude - all of which are supported explicitly by C++. Even if you check for endianness, your code could still end up broken and/or unportable (and, incidentally, that code i wrote above with the for loop will always work, no matter what).
Point 3: If you are going to copy a number into a char array like that because you want to transmit the number... you should probably be sure the char array uses the right size char. Despite common thought, char does not have to be 8 bits.
Point 4: You don't really want the binary representation of the number 99.9999999% of the time. You want the number to be transformed into (or from) a certain specific binary representation, and you can do that without knowing the original form. Raw memory dumps are almost always useless, because while the numbers might still be valid, the pointers are almost always not.
The moral of the story is: if you're just curious to see what the int looks like in memory, fine. But if this actually has a purpose, step back and look at what that purpose really is. Because almost always, this is the wrong way to go about doing things.
The following function will transform an unsigned number to network order on all platforms, all the time, regardless of architecture, without problems: | Code: |
std::vector<unsigned char> to_network_order(unsigned int number)
{
std::vector<unsigned char> result(sizeof(unsigned int));
for (int i = 0; i < sizeof(unsigned int); ++i)
result[i] = (number >> (CHAR_BIT * i)) & UCHAR_MAX;
return result;
} |
Or, if you want a fixed byte size (like 8 ): | Code: |
std::vector<unsigned char> to_network_order(unsigned int number, unsigned int byte_size = 8)
{
unsigned int const num_bytes_in_int = (sizeof(unsigned int) * CHAR_BIT) / byte_size;
unsigned int mask = 0;
for (int i = 0; i < byte_size; ++i)
mask = (mask << 1) | 0x1;
std::vector<unsigned char> result(num_bytes_in_int);
for (int i = 0; i < num_bytes_in_int; ++i)
result[i] = (number >> (byte_size * i)) & mask;
return result;
} |
Lots of room for improving efficiency and robustness in that, but it will be fast enough for most purposes (and if you really need it fast, it's not hard to make it much faster).