Преобразование массива Char в Long в C - PullRequest
4 голосов
/ 14 июля 2011

Этот вопрос может выглядеть глупо, но, пожалуйста, направьте меня У меня есть функция для преобразования длинных данных в массив символов

void ConvertLongToChar(char *pSrc, char *pDest)
{
    pDest[0] = pSrc[0];
    pDest[1] = pSrc[1];
    pDest[2] = pSrc[2];
    pDest[3] = pSrc[3];
}

И я вызываю вышеуказанную функцию следующим образом

long lTemp = (long) (fRxPower * 1000);
ConvertLongToChar ((char *)&lTemp, pBuffer);

Который работает нормально. Мне нужна аналогичная функция, чтобы отменить процедуру. Конвертировать массив символов в long Я не могу использовать atol или подобные функции.

Ответы [ 7 ]

9 голосов
/ 14 июля 2011

Вы можете сделать:

union {
 unsigned char c[4];
 long l;
} conv;

conv.l = 0xABC;

и получить доступ c[0] c[1] c[2] c[3].Это хорошо, так как не тратит впустую память и очень быстро, потому что нет никаких сдвигов или каких-либо назначений, кроме начального, и это работает в обе стороны.

7 голосов
/ 14 июля 2011

Оставляя бремя сопоставления порядка байтов с вашей другой функцией, вот один из способов:

unsigned long int l = pdest[0] | (pdest[1] << 8) | (pdest[2] << 16) | (pdest[3] << 24);

На всякий случай, вот соответствующее другое направление:

unsigned char pdest[4];
unsigned long int l;
pdest[0] = l         & 0xFF;
pdest[1] = (l >>  8) & 0xFF;
pdest[2] = (l >> 16) & 0xFF;
pdest[3] = (l >> 24) & 0xFF;

Переход от char[4] к длинному и обратно полностью обратим;переход от long к char[4] и обратно обратим для значений до 2 ^ 32-1.

Обратите внимание, что все это четко определено только для неподписанных типов.

(Мой пример little endian, если вы читаете pdest слева направо.)

Добавление: Я также предполагаю, что CHAR_BIT == 8.Как правило, в коде следует заменить кратные 8 на кратные CHAR_BIT.

7 голосов
/ 14 июля 2011

Простой способ - использовать memcpy:

char * buffer = ...;
long l;
memcpy(&l, buff, sizeof(long));

Однако это не учитывает порядок байтов, поэтому будьте осторожны, если вам нужно обмениваться данными между несколькими компьютерами.

3 голосов
/ 14 июля 2011

Если вы хотите обрабатывать sizeof (long) байтов памяти как один длинный, то вам нужно сделать следующее:

char char_arr[sizeof(long)];
long l;

memcpy (&l, char_arr, sizeof (long));

Это можно сделать, вставив каждый байт длинного с использованием сдвига битов ивставка, как показано ниже.

l = 0;
l |= (char_arr[0]);
l |= (char_arr[1] << 8);
l |= (char_arr[2] << 16);
l |= (char_arr[3] << 24);

Если вы хотите преобразовать строку "1234 \ 0" в 1234L, вам следует

l = strtol (char_arr, NULL, 10); /* to interpret the base as decimal */
0 голосов
/ 03 января 2015
char charArray[8]; //ideally, zero initialise
unsigned long long int combined = *(unsigned long long int *) &charArray[0];

Остерегайтесь строк, заканчивающихся нулем, так как в итоге вы скопируете любые байты за пределами нулевого терминатора в combined; таким образом, в приведенном выше присваивании charArray необходимо полностью инициализировать нулями для «чистого» преобразования.

0 голосов
/ 20 марта 2014

Это грязно, но работает:

unsigned char myCharArray[8];
// Put some data in myCharArray here...
long long integer = *((long long*) myCharArray);
0 голосов
/ 14 июля 2011

Работает ли это:

#include<stdio.h>

long ConvertCharToLong(char *pSrc) {
    int i=1;
    long result = (int)pSrc[0] - '0';
    while(i<strlen(pSrc)){
         result = result * 10 + ((int)pSrc[i] - '0');
         ++i;
    }
    return result;
}


int main() {
    char* str = "34878";
    printf("The answer is %d",ConvertCharToLong(str));
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...