简体   繁体   中英

How to convert bytes stored inside a buffer to a variable?

So I'm reading from a file descriptor which contains an int variable in its raw byte format.

So I'm doing:

char buffer[sizeof(int)];
ssize_t sizeOfFile = read(sock_fd, buffer, sizeof(int));

int extractedInt = ???;

How can I convert that buffer to an integer? I was thinking of memcpy but was wondering if there are better ways.

You could read directly an integer

int extractedInt;
ssize_t sizeOfFile = read(sock_fd, &extractedInt, sizeof(int));

read will read the size of an int bytes, and store them into extractedInt .

If your int is actually a string in a file you want to convert to an int , the procedure is a bit different.

#define SIZE 20

char buffer[SIZE]; // ensure there is enough space for a string containing an integer
ssize_t sizeOfFile = read(sock_fd, buffer, SIZE);

int extractedInt = atoi(buffer);  // convert string to integer

I can guess from your code that you're reading from the network. This is then not portable to just read a int from the buffer, in your network protocol you chose a certain endianness but you cannot expect that all the platforms where your program will run to have the same, so it will lead to bad convertions. And other proposed solutions of asking read to return an int will lead to the same problem.

So in your case, I can only advice to iterate through your array and compute the integer by progressively placing the bytes at the right place depending on the endianness of the platform.

You can detect the endianness of the build target platform by using the macro __BYTE_ORDER__ in GCC.

There is an example for network data that is big endian:

// construct an `int` with the bytes in the given buffer
// considering the buffer contains the representation
// of an int in big endian
int buffer_to_int(char* buffer, int buffer_size) {
    int result = 0;
    int i;
    char sign = buffer[0] & 0x80;
    char * res_bytes = (char*)&result; // this pointer allows to access the int bytes
    int offset = sizeof(int) - buffer_size;

    if( sign != 0 )
        sign = 0xFF;

    if( offset < 0 ) {
        // not representable with a `int` type
        // we chose here to return the closest representable value
        if( sign == 0 ) { //positive
            return INT_MAX;
        } else {
            return INT_MIN;
        }
    }

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
    for(i=0; i<buffer_size; i++) {
        res_bytes[i] = buffer[buffer_size-i-1]; // invert the bytes
    }

    for(i=0; i<offset; i++){
        res_bytes[buffer_size+i] = sign;
    }
#else
    // same endianness, so simply copy bytes using memcpy
    memcpy(&result + offset, buffer, buffer_size);

    for(i=0; i<offset; i++){
        res_bytes[i] = sign;
    }
#endif

    return result;
}

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