Преобразование шестнадцатеричной строковой константы в десятичное значение с использованием C - PullRequest
1 голос
/ 07 марта 2019

Следующая программа выдает результат в виде 0 вместо ожидаемого десятичного эквивалента шестнадцатеричной строковой константы.

#include <stdio.h>

int my_htoi(char[]);

int main(void) {
    printf("%d", my_htoi("0xABC"));
    return 0;
}

int my_htoi(char str[]) {
    int i, num = 0;
    for (i = 0; i != '\0'; ++i) {
        if (str[i+1] == 'x' || str[i+1] == 'X') {
            i = i + 1;
            continue;
        }
        if (str[i] >= '0' && str[i] <= '9') {
            num = num * 16 + (str[i] - '0');
        } else if (str[i] >= 'a' && str[i] <= 'f') {
            num = num * 16 + (str[i] - 'a' + 10);
        } else if (str[i] >= 'A' && str[i] <= 'F') {
            num = num * 16 + (str[i] - 'A' + 10);
        }
    }
    return num;
}

Хотя следующая программа работает нормально и выводит правильный десятичный эквивалент шестнадцатеричной строковой константы.

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

int my_htoi(char[]);

int main(void) {
    printf("%d", my_htoi("0xABC"));
    return 0;
}

int my_htoi(char str[]) {
    int i, num = 0;
    for (i = 0; i < strlen(str); ++i) {
        if (str[i+1] == 'x' || str[i+1] == 'X') {
            i = i + 1;
            continue;
        }
        if (str[i] >= '0' && str[i] <= '9') {
            num = num * 16 + (str[i] - '0');
        } else if (str[i] >= 'a' && str[i] <= 'f') {
            num = num * 16 + (str[i] - 'a' + 10);
        } else if (str[i] >= 'A' && str[i] <= 'F') {
            num = num * 16 + (str[i] - 'A' + 10);
        }
    }
    return num;
}

Единственная разница в том, как мы находим условие для цикла. Почему не работает проверка нулевого байта?

Ответы [ 2 ]

2 голосов
/ 07 марта 2019

Неверный код: i != '\0' проверяет, равен ли индекс 0.

for(i = 0; i != '\0'; ++i) {

Должно быть ниже, чтобы проверить, является ли элемент str[i] нулевым символом .

for(i = 0; str[i] != '\0'; ++i) {

Существуют другие проблемы неоправданное увеличение , int переполнение (лучше использовать unsigned здесь), неправильное x обнаружение - рассмотрим "0x0x0x1", ведущий - или +, char str[] -> const char str[], ...

1 голос
/ 08 марта 2019

В вашем коде есть некоторые проблемы:

  • индекс цикла i сравнивается с '\0' вместо str[i], вызывая немедленное завершение цикла с возвращаемым значением 0.

  • тест для x неверен: это приведет к преобразованию "1x2" в 2 вместо 1.

  • Вы принимаете буквы за пределами f и конвертируете их в цифры. Вместо этого функция должна прекратить анализ первого символа, который не является шестнадцатеричной цифрой.

Вот исправленная версия:

#include <stdio.h>

int my_htoi(const char[]);

int main(void) {
    printf("%d", my_htoi("0xABC"));
    return 0;
}

int my_htoi(const char str[]) {
    int i = 0, num = 0;
    if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
        i += 2;
    for (; str[i] != '\0'; ++i) {
        if (str[i] >= '0' && str[i] <= '9') {
            num = num * 16 + (str[i] - '0');
        } else if (str[i] >= 'a' && str[i] <= 'f') {
            num = num * 16 + (str[i] - 'a' + 10);
        } else if (str[i] >= 'A' && str[i] <= 'F') {
            num = num * 16 + (str[i] - 'A' + 10);
        } else {
            break;
        }
    }
    return num;
}
...