у меня есть vector<unsigned char>
и хочу поставить 4 байта Integer
в первые 4 элемента.
Есть ли более простой способ в C ++, чем маскировка, подобная этой:
myVector.at(0) = myInt & 0x000000FF;
myVector.at(1) = myInt & 0x0000FF00;
myVector.at(2) = myInt & 0x00FF0000;
myVector.at(3) = myInt & 0xFF000000;
std::vector
гарантированно хранится как один непрерывный блок данных(‡). Следовательно, можно лечить std::vector<unsigned char>
в основном так же, как unsigned char
буфер. Это означает, что вы можете memcpy
ваши данные в вектор, если вы уверены, что они достаточно велики:
#include <vector>
#include <cstring>
#include <cstdint>
int main()
{
std::int32_t k = 1294323;
std::vector<unsigned char> charvec;
if (charvec.size() < sizeof(k))
charvec.resize(sizeof(k));
std::memcpy(charvec.data(), &k, sizeof(k));
return 0;
}
Обратите внимание data()
функция std::vector
возвращает void*
во внутренний буфер вектора. Он доступен в C ++ 11 — в более ранних версиях можно использовать адрес первого элемента вектора, &charvec[0]
вместо.
Конечно, это очень необычный способ использования std::vector
и (в связи с необходимостью resize()
) немного опасно. Я верю, что у вас есть веские причины для этого.
(‡) Или, как сказано в стандарте:
(§23.3.6.1 / 1) […] Элементы вектора хранятся непрерывно, что означает, что если
v
этоvector<T, Allocator>
гдеT
это какой-то тип, кромеbool
тогда он подчиняется личности&v[n] == &v[0] + n for all 0 <= n < v.size().
Вы должны сдвинуть двоичные значения, чтобы это работало:
myVector.at(0) = (myInt & 0xFF);
myVector.at(1) = (myInt >> 8) & 0xFF;
myVector.at(2) = (myInt >> 16) & 0xFF;
myVector.at(3) = (myInt >> 24) & 0xFF;
Ваш код неверен:
int myInt = 0x12345678;
myVector.at(0) = myInt & 0x000000FF; // puts 0x78
myVector.at(1) = myInt & 0x0000FF00; // tries to put 0x5600 but puts 0x00
myVector.at(2) = myInt & 0x00FF0000; // tries to put 0x340000 but puts 0x00
myVector.at(3) = myInt & 0xFF000000; // tries to put 0x12000000 but puts 0x00
Вы можете сделать что-то похожее на следующее:
#include <vector>
#include <cstdio>
void
insert_int(std::vector<unsigned char>* container, int integer)
{
char* chars = reinterpret_cast<char*>(&integer);
container->insert(container->end(), chars, chars+sizeof(int));
}
int main(void)
{
std::vector<unsigned char> test_vector;
int test_int = 0x01020304;
insert_int(&test_vector, test_int);
return 0;
}
просто не забудьте учесть бесконечность. Моя машина печатает int в обратном порядке.
4,3,2,1
Ваше решение неверно, так как оно у вас есть. Что-то вроде:
std::vector<unsigned char> v(sizeof(int));
int myInt = 0x12345678;
for(unsigned i = 0; i < sizeof(int); ++i) {
v[i] = myInt & 0xFF;
myInt >>= 8;
}
Должно сработать. Это также более портативный (не предполагает int
4 байта).
Вот самый компактный способ:
myVector.at(0) = *((char*)&myInt+0);
myVector.at(1) = *((char*)&myInt+1);
myVector.at(2) = *((char*)&myInt+2);
myVector.at(3) = *((char*)&myInt+3);