C++ 将 int 存储在 char 数组中?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1522994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Store an int in a char array?
提问by Polaris878
I want to store a 4-byte int in a char array... such that the first 4 locations of the char array are the 4 bytes of the int.
我想将一个 4 字节的 int 存储在一个 char 数组中……这样 char 数组的前 4 个位置就是 int 的 4 个字节。
Then, I want to pull the int back out of the array...
然后,我想把 int 从数组中拉回来......
Also, bonus points if someone can give me code for doing this in a loop... IE writing like 8 ints into a 32 byte array.
此外,如果有人可以给我在循环中执行此操作的代码,则奖励积分...... IE 将 8 个整数写入 32 字节数组。
int har = 0x01010101;
char a[4];
int har2;
// write har into char such that:
// a[0] == 0x01, a[1] == 0x01, a[2] == 0x01, a[3] == 0x01 etc.....
// then, pull the bytes out of the array such that:
// har2 == har
Thanks guys!
谢谢你们!
EDIT:Assume intare 4 bytes...
编辑:假设int是 4 个字节...
EDIT2:Please don't care about endianness... I will be worrying about endianness. I just want different ways to acheive the above in C/C++. Thanks
EDIT2:请不要关心字节序......我会担心字节序。我只想用不同的方法在 C/C++ 中实现上述目标。谢谢
EDIT3:If you can't tell, I'm trying to write a serialization class on the low level... so I'm looking for different strategies to serialize some common data types.
EDIT3:如果你不知道,我正在尝试在低级别编写一个序列化类......所以我正在寻找不同的策略来序列化一些常见的数据类型。
回答by Pavel Minaev
Unless you care about byte order and such, memcpywill do the trick:
除非您关心字节顺序等,memcpy否则会起作用:
memcpy(a, &har, sizeof(har));
...
memcpy(&har2, a, sizeof(har2));
Of course, there's no guarantee that sizeof(int)==4on any particular implementation (and there are real-world implementations for which this is in fact false).
当然,sizeof(int)==4在任何特定实现上都不能保证(并且在现实世界的实现中,这实际上是错误的)。
Writing a loop should be trivial from here.
从这里开始编写循环应该是微不足道的。
回答by Pavel Minaev
Not the most optimal way, but is endian safe.
不是最佳方式,但字节序安全。
int har = 0x01010101;
char a[4];
a[0] = har & 0xff;
a[1] = (har>>8) & 0xff;
a[2] = (har>>16) & 0xff;
a[3] = (har>>24) & 0xff;
回答by stonemetal
Note: Accessing a union through an element that wasn't the last one assigned to is undefined behavior. (assuming a platform where characters are 8bits and ints are 4 bytes) A bit mask of 0xFF will mask off one character so
注意:通过不是最后一个分配给的元素访问联合是未定义的行为。(假设字符为 8 位,整数为 4 字节的平台)位掩码 0xFF 将屏蔽一个字符,因此
char arr[4];
int a = 5;
arr[3] = a & 0xff;
arr[2] = (a & 0xff00) >>8;
arr[1] = (a & 0xff0000) >>16;
arr[0] = (a & 0xff000000)>>24;
would make arr[0] hold the most significant byte and arr[3] hold the least.
将使 arr[0] 持有最高有效字节,而 arr[3] 持有最少。
edit:Just so you understand the trick & is bit wise 'and' where as && is logical 'and'. Thanks to the comments about the forgotten shift.
编辑:只是为了让您了解技巧 & 有点明智的“与”,而 && 是逻辑“与”。感谢关于被遗忘的转变的评论。
回答by Ashwin
int main() {
typedef union foo {
int x;
char a[4];
} foo;
foo p;
p.x = 0x01010101;
printf("%x ", p.a[0]);
printf("%x ", p.a[1]);
printf("%x ", p.a[2]);
printf("%x ", p.a[3]);
return 0;
}
Bear in mind that the a[0] holds the LSB and a[3] holds the MSB, on a little endian machine.
请记住,在小端机器上,a[0] 保存 LSB,a[3] 保存 MSB。
回答by Sinan ünür
#include <stdio.h>
int main(void) {
char a[sizeof(int)];
*((int *) a) = 0x01010101;
printf("%d\n", *((int *) a));
return 0;
}
Keep in mind:
记住:
A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined.
指向对象或不完整类型的指针可以转换为指向不同对象或不完整类型的指针。如果结果指针没有正确对齐指向的类型,则行为未定义。
回答by GManNickG
Don't use unions, Pavel clarifies:
不要使用联合,Pavel 澄清说:
It's U.B., because C++ prohibits accessing any union member other than the last one that was written to. In particular, the compiler is free to optimize away the assignment to
intmember out completely with the code above, since its value is not subsequently used (it only sees the subsequent read for thechar[4]member, and has no obligation to provide any meaningful value there). In practice, g++ in particular is known for pulling such tricks, so this isn't just theory. On the other hand, usingstatic_cast<void*>followed bystatic_cast<char*>is guaranteed to work.
它是 UB,因为 C++ 禁止访问除最后一个写入的联合成员之外的任何联合成员。特别是,编译器可以自由地
int使用上面的代码完全优化掉对member out的赋值,因为它的值不会随后被使用(它只看到该char[4]成员的后续读取,并且没有义务在那里提供任何有意义的值) . 在实践中,特别是 g++ 以拉这种技巧而闻名,所以这不仅仅是理论。另一方面,使用static_cast<void*>后跟static_cast<char*>保证可以工作。
– Pavel Minaev
— 帕维尔·米纳耶夫
回答by Richard Corden
You can also use placement new for this:
您还可以为此使用新的展示位置:
void foo (int i) {
char * c = new (&i) char[sizeof(i)];
}
回答by Schlameel
#include <stdint.h>
int main(int argc, char* argv[]) {
/* 8 ints in a loop */
int i;
int* intPtr
int intArr[8] = {1, 2, 3, 4, 5, 6, 7, 8};
char* charArr = malloc(32);
for (i = 0; i < 8; i++) {
intPtr = (int*) &(charArr[i * 4]);
/* ^ ^ ^ ^ */
/* point at | | | */
/* cast as int* | | */
/* Address of | */
/* Location in char array */
*intPtr = intArr[i]; /* write int at location pointed to */
}
/* Read ints out */
for (i = 0; i < 8; i++) {
intPtr = (int*) &(charArr[i * 4]);
intArr[i] = *intPtr;
}
char* myArr = malloc(13);
int myInt;
uint8_t* p8; /* unsigned 8-bit integer */
uint16_t* p16; /* unsigned 16-bit integer */
uint32_t* p32; /* unsigned 32-bit integer */
/* Using sizes other than 4-byte ints, */
/* set all bits in myArr to 1 */
p8 = (uint8_t*) &(myArr[0]);
p16 = (uint16_t*) &(myArr[1]);
p32 = (uint32_t*) &(myArr[5]);
*p8 = 255;
*p16 = 65535;
*p32 = 4294967295;
/* Get the values back out */
p16 = (uint16_t*) &(myArr[1]);
uint16_t my16 = *p16;
/* Put the 16 bit int into a regular int */
myInt = (int) my16;
}
回答by pari
char a[10];
int i=9;
a=boost::lexical_cast<char>(i)
found this is the best way to convert char into int and vice-versa.
发现这是将 char 转换为 int 的最佳方法,反之亦然。
alternative to boost::lexical_cast is sprintf.
boost::lexical_cast 的替代方法是 sprintf。
char temp[5];
temp[0]="h"
temp[1]="e"
temp[2]="l"
temp[3]="l"
temp[5]='union value {
int i;
char bytes[sizof(int)];
};
value v;
v.i = 2;
char* bytes = v.bytes;
'
sprintf(temp+4,%d",9)
cout<<temp;
output would be :hell9
输出将是:hell9

