简体   繁体   中英

how to convert digits from a integer in a byte array in C++

i tried to convert the digits from a number like 9140 to a char array of bytes, i finally did it, but for some reason one of the numbers is converted wrong.

The idea is separate each digit an convert it in a byte[4] and save it a global array of bytes, that means that array have a digit each 4 positions, i insert each digit at the end of array and finally i insert the amount of digits at the end of the array.

the problem is randomly with some values, for example for the value 25 it works but for 9140 it return me 9040, which could be the problem? this is the code:

void convertCantToByteArray4Digits(unsigned char *bufferDigits,int cant){
    //char bufferDigits[32];
    int bufferPos=20;
    double cantAux=cant;
    int digit=0,cantDigits=0;
    double subdigit=0;
    while(cantAux > 0){
        cout<<"VUELTA"<<endl;
        cantAux/=10;
        cout<<"cantAux/=10:"<<cantAux<<endl;
        cout<<"floor"<<floor(cantAux)<<endl;
        subdigit=cantAux-floor(cantAux);
        cout<<"subdigit"<<subdigit<<endl;
        digit=static_cast<int>(subdigit*10);
        cout<<"digit:"<<subdigit*10<<endl;
        cantAux=cantAux-subdigit;
        cout<<"cantAux=cantAux-subdigit:"<<cantAux<<endl;
        bufferDigits[bufferPos-4] = (digit >> 24) & 0xFF;
        std::cout<<static_cast<int>(bufferDigits[bufferPos-4])<<std::endl;
        bufferDigits[bufferPos-3] = (digit >> 16) & 0xFF;
        std::cout<<static_cast<int>(bufferDigits[bufferPos-3])<<std::endl;
        bufferDigits[bufferPos-2] = (digit >> 8) & 0xFF;
        std::cout<<static_cast<int>(bufferDigits[bufferPos-2])<<std::endl;
        bufferDigits[bufferPos-1] = (digit) & 0xFF;
        std::cout<<static_cast<int>(bufferDigits[bufferPos-1])<<std::endl;
        /*bufferDigits[0] = digit >> 24;
        std::cout<<bufferDigits[0]<<std::endl;
        bufferDigits[1] = digit >> 16;
        bufferDigits[2] = digit >> 8;
        bufferDigits[3] = digit;*/
        bufferPos-=4;
        cantDigits++;
    }
    cout<<"sizeof"<<sizeof(bufferDigits)<<endl;
    cout<<"cantDigits"<<cantDigits<<endl;
    bufferPos=24;
    bufferDigits[bufferPos-4] = (cantDigits) >> 24;
        //std::cout<<bufferDigits[bufferPos-4]<<std::endl;
    bufferDigits[bufferPos-3] = (cantDigits) >> 16;
    bufferDigits[bufferPos-2] = (cantDigits) >> 8;
    bufferDigits[bufferPos-1] = (cantDigits);

}

the bufferDigits have a size of 24 bytes, the cant parameter is the number to convert, i receive any question about my code.

I feel this is the most c++ way that probably answers your question, if I understood correctly:

#include <string>
#include <iterator>
#include <iostream>
#include <algorithm>

template <typename It>
It tochars(unsigned int i, It out)
{
    It save = out;

    do    *out++ = '0' + i%10;
    while (i/=10);

    std::reverse(save, out);
    return out;
}

int main()
{
    char buf[10];

    char* end = tochars(9140, buf);
    *end = 0; // null terminate

    std::cout << buf << std::endl;
}

Instead of using a double and the floor function, just use an int and the modulus operator instead.

void convertCantToByteArray4Digits(unsigned char *bufferDigits,int cant)
{
  int bufferPos=20;
  int cantAux=cant;
  int digit=0,cantDigits=0;
  while(cantAux > 0)
  {
    cout<<"VUELTA"<<endl;
    digit = cantAux % 10;
    cout<<"digit:"<<digit<<endl;
    cantAux /= 10;
    cout<<"cantAux/=10:"<<cantAux<<endl;
    bufferDigits[bufferPos-4] = (digit >> 24) & 0xFF;
    std::cout<<static_cast<int>(bufferDigits[bufferPos-4])<<std::endl;
    bufferDigits[bufferPos-3] = (digit >> 16) & 0xFF;
    std::cout<<static_cast<int>(bufferDigits[bufferPos-3])<<std::endl;
    bufferDigits[bufferPos-2] = (digit >> 8) & 0xFF;
    std::cout<<static_cast<int>(bufferDigits[bufferPos-2])<<std::endl;
    bufferDigits[bufferPos-1] = (digit) & 0xFF;
    std::cout<<static_cast<int>(bufferDigits[bufferPos-1])<<std::endl;
    bufferPos-=4;
    cantDigits++;
  }

Why not use a union?

union {
  int i;
  char c[4];
};

i = 2530;
// now c is set appropriately

Or memcpy?

memcpy(bufferDigits, &cant, sizeof(int));

Why so complicated? Just divide and take remainders. Here's a reentrant example to which you provide a buffer, and you get back a pointer to the beginning of the converted string:

char * to_string(unsigned int n, char * buf, unsigned int len)
{
  if (len < 1) return buf;

  buf[--len] = 0;

  if (n == 0 && len > 0) { buf[--len] = '0'; }

  while (n != 0 && len > 0) { buf[--len] = '0' + (n % 10); n /= 10; }

  return &buf[len];
}

Usage: char buf[100]; char * s = to_string(4160, buf, 100); char buf[100]; char * s = to_string(4160, buf, 100);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM