C++: Преобразуване на unsigned long long int във вектор‹char› и обратно

Може ли някой да ми каже как да конвертирам unsigned long long int във вектор и обратно.

За конвертиране от unsigned long long int във вектор, опитах следното:

unsigned long long int x;
vector<char> buf(sizeof(x));
memcpy( &buf[0], &x, sizeof( x ) );

Когато тествах за x = 1234567890, не успя. Но когато го опитах за по-малки стойности на x (да речем 1-100), работи...

За конвертиране на вектор в unsigned long long int използвах:

   unsigned long long int =  (unsigned long long int)buf[0];

Може ли някой да ми каже как да го направя.


person veda    schedule 25.01.2012    source източник
comment
да, опитвам се да разделя цялото число на вектор‹char›, за да мога да го изпратя от клиента към сървъра и да го прочета обратно.   -  person veda    schedule 25.01.2012
comment
Ако искате да направите това, вероятно трябва да обмислите комбинирането на решението на Mark B в шаблонни функции, които могат да пишат/четат произволен тип във вашия вектор‹char› безопасно.   -  person Benj    schedule 25.01.2012


Отговори (3)


Само не забравяйте, че копирането на байтове наоколо няма да бъде преносимо между платформи. Вашият memcpy изглежда добре, така че защо не го създадете отново на връщане? Това, което сте написали, просто взема първия байт от вектора и го преобразува в unsigned long long, което обяснява защо работи за малки числа.

Опитайте това вместо това, за да получите обратно стойността от вектора:

unsigned long long int x;
memcpy(&x, &buf[0], sizeof(x));
person Mark B    schedule 25.01.2012
comment
Хе-хе, и ако опитате текущия му подход върху система с голям порядък, buf[0] ще съдържа нещо само ако имате наистина голяма стойност на x. - person Benj; 25.01.2012

Вместо да memcpyвлизате директно във вектора, можете да използвате std::vector::assign, за да извършите копирането.

#include <iostream>
#include <vector>

int main()
{
  unsigned long long int x = 0x0807060504030201;
  std::vector<char> v;

  v.assign( reinterpret_cast<char *>( &x ), reinterpret_cast<char *>( &x ) + sizeof( x ) );

  for( auto i = v.begin(); i != v.end(); ++i ) {
    std::cout << std::hex << static_cast<int>( *i ) << ' ';
  }
  std::cout << std::endl;

  // To convert back
  auto y = *reinterpret_cast<unsigned long long int *>( &v[0] );
  std::cout << "y = " << std::hex << std::showbase << y << std::endl;

  return 0;
}

Изход:

1 2 3 4 5 6 7 8 
y = 0x807060504030201
person Praetorian    schedule 25.01.2012
comment
Как да го запазя в обратен ред, имам предвид, че изходът от печат ще бъде 8 7 6 5 4 3 2 1? - person rank1; 08.05.2013
comment
@cygi1989 Използвайте std::reverse. След v.assign(...); добавете std::reverse(v.begin(), v.end()); - person Praetorian; 08.05.2013
comment
Страхотен. Възможно ли е да му присвоя най-малкия възможен вектор, да кажем, че имам функция, която връща малкия брой байтове, необходими за съхраняване на дадено цяло число. Как бих го направил? - person rank1; 08.05.2013
comment
@cygi1989 Не съм сигурен какво питаш. Защо не публикувате друг въпрос? - person Praetorian; 08.05.2013

Трябва да промените последния си ред:

memcpy( &buf[0], reinterpret_cast<char*>(&x), sizeof( x ) );

Редактиране Говорех глупости, този ред е добре такъв, какъвто е, но обратното ви преобразуване е лошо - преобразувате стойността, вместо показалеца:

unsigned long long int val = *reinterpret_cast<unsigned long long int*>(&buf[0]);
person Björn Pollex    schedule 25.01.2012
comment
@MarkB: И аз го разбрах - бях объркан за момент. - person Björn Pollex; 25.01.2012