-2

How can I convert an unsigned char array that contains letters into an integer. I have tried this so for but it only converts up to four bytes. I also need a way to convert the integer back into the unsigned char array .

int buffToInteger(char * buffer)
{
    int a = static_cast<int>(static_cast<unsigned char>(buffer[0]) << 24 |
        static_cast<unsigned char>(buffer[1]) << 16 | 
        static_cast<unsigned char>(buffer[2]) << 8 | 
        static_cast<unsigned char>(buffer[3]));
    return a;
}
Doku Software
  • 11
  • 1
  • 6
  • To type pun an array of char to integer use [use memcpy or maybe bit_cast](https://stackoverflow.com/a/51228315/1708801) – Shafik Yaghmour Aug 01 '18 at 17:06
  • What is the *real* problem that you want to solve this way? With an [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) and some example input, what would the output be? What output do your current attempt give? And please [read about how to ask good questions](http://stackoverflow.com/help/how-to-ask), and also [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – Some programmer dude Aug 01 '18 at 17:07
  • 2
    It is not clear what "conversion" you need – Slava Aug 01 '18 at 17:07
  • Because an integer is 32 bit, it is impossible to narrow more than 4 chars (8 bit) to it's size without losing information. – Czipperz Aug 01 '18 at 17:24
  • @Czipperz "Because an integer is 32 bit" no it is not, it can be 32 bit but can be different – Slava Aug 01 '18 at 17:28
  • Begin by saying, in words, what characters the array is allowed to contain, and how they should be converted into an integer value. – Pete Becker Aug 01 '18 at 17:28
  • @Slava I am aware that the standard just requires them to be greater in size than a `short`, less than a `long`, and not even having 8 bits per byte. But on MSVC, it is 32 bits, and I have reason to believe it is the same on other platforms. – Czipperz Aug 01 '18 at 17:34
  • @Czipperz you aware wrong, `int` must be greater or **equal** to short and less or **equal** to long. And there are platforms where it is different than 32bits indeed. – Slava Aug 01 '18 at 17:39
  • @Slava MSVC has 32 bit integers. x86_64 Linux on GCC and CLANG have 32 bit integers. On Mac OSX GCC int is 32 bit. – Czipperz Aug 01 '18 at 17:46
  • You are completely correct that the standard does not specify, but in actuality all major platforms use 32 bit ints – Czipperz Aug 01 '18 at 17:47
  • And ARM uses 32 bit ints as well. – Czipperz Aug 01 '18 at 17:48
  • @Czipperz -- you're absolutely right that there are platforms where `int` is 32 bits wide. There are also platforms where it is not. If you write code on the assumption that an `int` is 32 bits wide, sooner or later you'll get burned. – Pete Becker Aug 01 '18 at 19:44
  • Ok. I guess the point of my example is that event if int is a million bytes wide, it still looses information stored in the original string. This is because `char array[REALLY_BIG_SIZE]` still can't store all strings. – Czipperz Aug 01 '18 at 20:13

3 Answers3

0

It looks like you're trying to use a for loop, i.e. repeating a task over and over again, for an in-determinant amount of steps.

unsigned int buffToInteger(char * buffer, unsigned int size)
{
    // assert(size <= sizeof(int));
    unsigned int ret = 0;
    int shift = 0;
    for( int i = size - 1; i >= 0, i-- ) {
        ret |= static_cast<unsigned int>(buffer[i]) << shift;
        shift += 8;
    }
    return ret;
}
Nicholas Pipitone
  • 4,002
  • 4
  • 24
  • 39
  • And that could quite quickly lead to a shift larger than the size of `unsigned int`, which leads to UB. – Some programmer dude Aug 01 '18 at 17:15
  • @OP If your issue was with the casting syntax, and not with programming in general, then you obviously know what a for loop is, so know that my comment wasn't intending to be condescending, but rather informative for a newb. – Nicholas Pipitone Aug 01 '18 at 17:16
  • @Someprogrammerdude Well, yes, but there's nothing to do in that case. `long` is also valid, but if the OP wants to use more than just a couple characters then it's a useless endeavor as C++ just can't store those integers at all. – Nicholas Pipitone Aug 01 '18 at 17:18
  • I think `ret = (ret << 8) | *buffer++;` would be simpler, but it is not clear if OP needs such conversion at all. – Slava Aug 01 '18 at 17:18
0

What I think you are going for is called a hash -- converting an object to a unique integer. The problem is a hash IS NOT REVERSIBLE. This hash will produce different results for hash("WXYZABCD", 8) and hash("ABCD", 4). The answer by @Nicholas Pipitone DOES NOT produce different outputs for these different inputs.

Once you compute this hash, there is no way to get the original string back. If you want to keep knowledge of the original string, you MUST keep the original string as a variable.

int hash(char* buffer, size_t size) {
    int res = 0;
    for (size_t i = 0; i < size; ++i) {
        res += buffer[i];
        res *= 31;
    }
    return res;
}
Czipperz
  • 3,268
  • 2
  • 18
  • 25
0

Here's how to convert the first sizeof(int) bytes of the char array to an int:

int val = *(unsigned int *)buffer;

and to convert in back:

*(unsigned int *)buffer = val;

Note that your buffer must be at least the length of your int type size. You should check for this.

Ton Plooij
  • 2,583
  • 12
  • 15