С Новым годом! Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.90/40: Рейтинг темы: голосов - 40, средняя оценка - 4.90
7 / 8 / 9
Регистрация: 15.07.2015
Сообщений: 56
1

Фунция htoi. 2.3 (Преобразование hex строки в число)

19.07.2015, 15:34. Показов 7215. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Выкладываем свои решение по задачи 2.3, преоброзование hex строки в число. Моё решение:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
 
int htoi(char s[]);
 
main()
{
char test[12]="0xd978c9";
printf("%s\n",test);
printf("%x\n",htoi(test));
printf("%d\n",htoi(test));
getch();
}
 
 
htoi(char s[])
{
int i,n;          
 
n=0;
 
if(s[1] == 'x')
    for(i=2;isdigit(s[i]) || tolower(s[i]) >= 'a' && tolower(s[i]) <= 'f';i++)
    {
    if(isdigit(s[i]))
     n=n*16+(s[i]-'0'); 
    else
      n=n*16+(10+tolower(s[i])-'a'); 
    } 
else
    for(i=0;isdigit(s[i]) || tolower(s[i]) >= 'a' && tolower(s[i]) <= 'f';i++)
    {
    if(isdigit(s[i]))
     n=n*16+(s[i]-'0'); 
    else
      n=n*16+(10+tolower(s[i])-'a'); 
    }
return n;          
}
1
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.07.2015, 15:34
Ответы с готовыми решениями:

Простое преобразование строки в HEX
Помогите перевести вводимое значение в поле Edit1-&gt;Text ASCII в 16-ричном представлении в символ...

Преобразование строки в hex для отправки через COM порт
Вопрос, как вот это byte = { 0xAA, 0x00, 0x24, 0x00, 0x00, 0x24, 0x55 }; послать в COM порт. Точнее...

C++ Builder 6.0 - преобразование hex данных с компорта в вещественное число двойной точности
Доброго всем времени суток. Данные с компорта записываю во временный буфер queue &lt;unsigned char&gt;...

Как разбить одно число HEX число на два числа HEX ?
Задача в том, что бы одно число в виде HEX (к примеру 0xD681) разбить на 2 числа HEX (из 0xD681 - &gt;...

9
1 / 1 / 7
Регистрация: 06.07.2015
Сообщений: 55
19.07.2015, 16:19 2
Что за задача 2.3?...
0
7 / 8 / 9
Регистрация: 15.07.2015
Сообщений: 56
19.07.2015, 16:27  [ТС] 3
Из учебника по си кернига и ритчи.
0
1 / 1 / 7
Регистрация: 06.07.2015
Сообщений: 55
19.07.2015, 16:32 4
Бедный Керниган...
0
594 / 416 / 136
Регистрация: 02.10.2008
Сообщений: 1,779
Записей в блоге: 1
20.07.2015, 21:32 5
Ну Керниган, наверное ставил условие не использовать библиотечные функции, вроде isdigit()...
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include    <stdint.h>
#include    <stdio.h>
#include    <stdlib.h> 
 
uint64_t    str2hex(const char *s);
const char str[]="0XbAdB349D846";
 
int main(int argc,char** argv)
{  
    
    
    printf("String \"%s\" is a 0X%llX\n",str,str2hex(str));
    return 0;
}
 
uint64_t    str2hex(const char *s)
{   uint64_t res=0;
    size_t  i=2;
    
    if(s == NULL)
        exit(EXIT_FAILURE);
  
    if((s[0] == 0) || (s[0] != '0'))
        exit(EXIT_FAILURE);
    
    if((s[1] == 0) || ((s[1] != 'x') && (s[1] != 'X')))
        exit(EXIT_FAILURE);
    
    if(s[2] == 0)
        exit(EXIT_FAILURE);
    
    do
    {   res<<=4;
        if(s[i]>='0' && s[i]<='9') 
            res=res | (uint8_t)(s[i]-'0');
        else
            if(s[i]>='A' && s[i]<='F') 
                res=res | (uint8_t)(s[i]-'A'+10);
            else
                if(s[i]>='a' && s[i]<='f')
                    res=res | (uint8_t)(s[i]-'a'+10);
                else
                    exit(EXIT_FAILURE);
        
        i++;
    }
    while(i<18 && s[i] != 0);
    
    return res;
}
Добавлено через 13 минут
Табличный метод будет ещё быстрее - но лень писать....
1
838 / 641 / 940
Регистрация: 26.06.2015
Сообщений: 1,409
21.07.2015, 01:13 6
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

Вот мой вариант.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <stdio.h>
#include <errno.h>
 
size_t hex_to_num(const char* s){
    char   c;
    size_t n = 0, i = 0;
    
    errno = 0;
    if(*s != '0')
        goto err;
    c = *(++s) & 0xDF;
    if(c != 'X')
        goto err;
    if(! *(++s))
        goto err;
 
    for(; *s; ++s, i += 4){
        if(*s >= '0' && *s <= '9')
            n = (n << 4) | (size_t)(*s - '0');
        else {
            c = *s & 0xDF;
            if(c >= 'A' && c <= 'F')
                n = (n << 4) | (size_t)(c - 'A' + 10);
            else
                goto err;
        }
    }
 
    //проверим на переполнение
    if(i > (sizeof(size_t) << 3))
        errno = ERANGE;
    return n;
err:
    errno = EINVAL;
    return 0;
}
 
 
int main(void){
    size_t a, b;
 
    a = 0x12345678;
    b = hex_to_num("0x12345678");
    printf("%u\n%u\n\n", a, b);
 
    a = 0xff00FFAA;
    b = hex_to_num("0xff00FFAA");
    printf("%u\n%u\n\n", a, b);
 
    a = 0XABCDEF00;
    b = hex_to_num("0XABCDEF00");
    printf("%u\n%u\n\n", a, b);
    return 0;
}
Результат работы кода
1
204 / 26 / 5
Регистрация: 22.05.2015
Сообщений: 357
22.07.2015, 20:39 7
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <ctype.h>
#include <stdio.h>
#include <stdint.h>
 
int32_t get_byte (int8_t byte)
{
    register int32_t res = 9;
 
    switch (byte) {
        case 'F': case 'f': ++res;
        case 'E': case 'e': ++res;
        case 'D': case 'd': ++res;
        case 'C': case 'c': ++res;
        case 'B': case 'b': ++res;
        case 'A': case 'a': ++res;
            break;
        default:
            res = (byte >= '0' && byte <= '9') ? byte - '0' : -1;
    }
    return res;
}
 
#define TETRAD (4)
#define TETRAD_COUNT (8)
#define H2N_EINVAL (0x8000000000000000UL)
#define H2N_E2BIG (0x4000000000000000UL)
 
/* возвращаемый результат 4 байта. Старшие 4 байта - флаг ошибки */
uint64_t hex_str2num (char * str)
{
    uint64_t res = 0, i = 0;
 
    if (*str && *str++ != '0') {
        return H2N_EINVAL;
    }
    if (*str && tolower(*str++) != 'x') {
        return H2N_EINVAL;
    }
 
    for (;*str && i < TETRAD_COUNT; ++str, ++i) {
 
        int8_t ret = get_byte (*str);
 
        if (ret == -1) {
            res |= H2N_EINVAL;
        } else {
 
            res =  res & H2N_EINVAL | res << TETRAD;
            res |= ret;
        }
    }
    return *str ? res | H2N_E2BIG : res;
}
 
int main (void)
{
    char * test[] = {"0xAABBCCDD", "0x00FF2233", "0xGGHHDDFF", "0xAABBAABBAABB"};
    int i = 0;
 
    while(i < 4) {
        printf ("%lX\n", hex_str2num(test[i++]));
    }
 
    return 0;
}
0
594 / 416 / 136
Регистрация: 02.10.2008
Сообщений: 1,779
Записей в блоге: 1
22.07.2015, 21:47 8
Разленился и нарисовал табличный метод - имеем только три(два в условии цикла) сравнения на тетраду:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include    <stdint.h>
#include    <stdio.h>
#include    <stdlib.h> 
 
const   char    table[256]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
 
 
uint64_t    str2hex(const char *s);
const char str[]="0XaBcmvd126543456F";
 
int main(int argc,char** argv)
{  /* int i,j;
    
    printf("const\tchar\ttable[256]={");
    for(i=0;i<16;i++)
    {   
        for(j=0;j<16;j++)
         printf("0x00,");
        printf("\n\t\t\t\t\t\t\t");
    }
    printf("};\n");
    */
    printf("String \"%s\" is a 0X%llX\n",str,str2hex(str));
    return 0;
}
 
uint64_t    str2hex(const char *s)
{   uint64_t res=0;
    size_t  i=0;
    
    if(s == NULL)
        exit(EXIT_FAILURE);
  
    if(*s == 0)
        exit(EXIT_FAILURE);
    
    if(*s != '0')
        exit(EXIT_FAILURE);
    
    s++;
    
    if(*s == 0)
        exit(EXIT_FAILURE);
    
    if((*s != 'x') && (*s != 'X'))
        exit(EXIT_FAILURE);
    
    s++;
    
    while((*s != 0) && i < 16)
    {   
        if(table[*s] != 0)
        {
            res = (res << 4) | table[*s];
            i++;
        }
/*        else 
            exit(EXIT_FAILURE); 
            remove a comment if you need a strict check
            */
        s++; 
    }
 
    return res;
}
1
204 / 26 / 5
Регистрация: 22.05.2015
Сообщений: 357
22.07.2015, 22:06 9
drfaust, а написать set_table вместо ручного заполнения?
0
594 / 416 / 136
Регистрация: 02.10.2008
Сообщений: 1,779
Записей в блоге: 1
22.07.2015, 22:24 10
Зачем?
C
1
2
3
4
5
6
7
8
9
10
11
/* int i,j;
    
    printf("const\tchar\ttable[256]={");
    for(i=0;i<16;i++)
    {   
        for(j=0;j<16;j++)
         printf("0x00,");
        printf("\n\t\t\t\t\t\t\t");
    }
    printf("};\n");
    */
Да и пишется это элементарно... Однако тем, кто решится использовать данные йенкции придётся не забывать вызывать этот самый set_table, а так одна простая функция... В конце концов в пустом массиве нужно 22 буковки изменить - делов на 5мин.
0
22.07.2015, 22:24
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.07.2015, 22:24
Помогаю со студенческими работами здесь

Фунция, проверяющая, является ли число степенью числа 5
Описать функцию IsPower5(K) логического типа, возвращающую True, если целый параметр K (&gt; 0)...

преобразование из строки в число
как преобразовать из строки в число? если такое было то ткните в тему. в моём случае надо...

Преобразование строки в число
Программа преобразует введенную строку в число. Но на 9 строке есть ошибка: Нет перегруженной...

Преобразование строки в число
Здравствуйте, господа форумчане Допустим, имеем строку: var str = &quot;0xFF&quot;; Надо преобразовать...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru