2015-04-08 2 views
1

у меня есть строка с IP-адресом:C: Синтаксический Hex строка без знака длинного

символа * input_string = "fe80000000000000022318fffeedef59";

И мне нужно, чтобы преобразовать его в беззнаковое долго:

без знака длиной L = 0xfe80000000000000022318fffeedef59;

Я попробовал несколько кодов, но ни один не работает, вот что я сделал:

#include <stdio.h> 
#include <stdlib.h> 
void main() 
{ 
    char *input_string = "fe80000000000000022318fffeedef59"; 
    printf("input_string : %s\n\n", input_string); 

    unsigned long l1 = strtol(input_string, NULL, 16); 
    printf("unsigned long l1 = strtol(input_string, NULL, 16) : l1 = %lx \n\n", l1); 

    unsigned long l2 = atol(input_string); 
    printf("unsigned long l2 = atol(input_string) : l2 = %lx \n\n", l2); 
} 

И выход:

input_string: fe80000000000000022318fffeedef59

без знака длиной l1 = strtol (input_string, NULL, 16): l1 = 7fffffffffffffff

без знака long l2 = atol (input_string): l2 = 0

+2

Для хранения значения из 32-байтовой шестнадцатеричной строки вам понадобится 128-разрядная цифровая переменная. –

ответ

1

Как @Weather Vane комментарии: " Вам понадобится 128-битная числовая переменная для хранения значения из 32-b yte hex string "

Может использовать sscanf() для сохранения в 2 64-битных целых числа.

#include <stdio.h> 
#include <stdint.h> 
int main(void) { 
    uint64_t add[2]; 
    char *input_string = "fe80000000000000022318fffeedef59"; 
    if (2 != sscanf(input_string, "%16" SCNx64 "%16" SCNx64, &add[0], &add[1])) { 
    return -1; 
    } 
    printf("%016" PRIx64 "%016" PRIx64 , add[0], add[1]); 
    return 0; 
} 
0

Ваш номер слишком длинный. Вы должны проверить статус возврата функций strtol и atol.

3

Ваша входная строка (32 байт) соответствует очень большому шестнадцатеричному номеру. Для хранения 32-байтовой строки, такой как этот, вам потребуется 16-байтовый (128-разрядный) тип данных. Но unsigned long - всего 8 байт. Вот почему вы получаете такой результат.

0

Вот что я, наконец, сделал.

#include <stdio.h> 
#include <string.h> 

void big_hex_string_to_long_array(char *); 

void main(void) 
{ 
    char *ipv6_string = "FE800000000000000202B3FFFE1E8329"; 

    big_hex_string_to_long_array(ipv6_string); 

} 

/* 
    * The ipv6 address is 128 bits long, too much to process in a single block. 
    * Here I split the address in four equals parts of 32 bits which can be stored 
    * in an long int (4 Bytes). 
    */ 
void big_hex_string_to_long_array(char * hex_string) 
{ 
    // create two buffers, one for the most significants bytes and the other for the lowest significants bytes 
    char buf_1[8+1]; // +1 : the space for '\0' 
    char buf_2[8+1]; 
    char buf_3[8+1]; 
    char buf_4[8+1]; 

    // copy each half in each buffers and add ending character 
    memcpy(buf_1, &(*hex_string), sizeof(char)* 8);  // copy the 8 first characters in buf_1 
    buf_1[8]='\0';      // set the last character 
    memcpy(buf_2, &(*hex_string)+8, sizeof(char)* 8); // copy the 8 next characters in buf_2 
    buf_2[8]='\0';      //...      
    memcpy(buf_3, &(*hex_string)+16, sizeof(char)* 8); 
    buf_3[8]='\0'; 
    memcpy(buf_4, &(*hex_string)+24, sizeof(char)* 8); 
    buf_4[8]='\0'; 

    printf("\nchar arrays : \nbuf1 = %s\nbuf2 = %s\nbuf3 = %s\nbuf4 = %s\n",buf_1, buf_2, buf_3, buf_4); 

    // store each buffer as unsigned long 
    long l1 = strtol(buf_1, NULL, 16);  // convert string to long 
    long l2 = strtol(buf_2, NULL, 16); 
    long l3 = strtol(buf_3, NULL, 16); 
    long l4 = strtol(buf_4, NULL, 16); 

    printf("\nlong int : \nl1 = %lx\nl2 = %lx\nl3 = %lx\nl4 = %lx\n",l1, l2, l3, l4); 
} 

Выход

символьные массивы:

BUF1 = FE800000

buf2 = 00000000

buf3 = 0202B3FF

buf4 = FE1E8329

длинные INT:

l1 = fffffffffe800000

l2 = 0

l3 = 202b3ff

L4 = fffffffffe1e8329

+0

Поскольку ваш 'unsigned long', очевидно, 8-байтовый, может использовать 2, а не 4 из них. Кроме того, рекомендуем 'unsigned long'. Может даже попробовать 'uintmax_t'. – chux

+0

strtol() return long, поэтому мои строки должны быть 4 байта, поэтому я использовал длинный тип данных – JeanRene

+0

Чтобы сохранить в 'unsigned long', используйте' strtoul() '. Чтобы сохранить в 'uintmax_t', используйте' strtoumax() '. Или нужен код для использования 'strtol()'? – chux

Смежные вопросы