Преобразование базы 20 в int - PullRequest
0 голосов
/ 05 марта 2019

Я пытаюсь преобразовать базу 20 в int. Например, если у меня есть "1A", его необходимо преобразовать в 30 и так далее. Я разработал код, но он дает проблемы при запуске. Код, как показано ниже в C языке программирования:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("Hello world!\n");
    char converted[20] = "1A";
    itov(converted);

    return 0;
}

void itov(char vigesimalStr[])
{
    int length = 0;
    for (int i = 0; vigesimalStr[i] != '\0'; i++)
    {
        length++;
    }

    int base = 20;
    int result = 0;
    int power = 1;
    int num = 0;
    for (int j = length; j >= 0; j--)
    {
        if (val(vigesimalStr[j]) >= base)
        {
            printf("Invalid Number");
            return -1;
        }

        num += val(vigesimalStr[j]) * power;
        power = power * base;

    }

}

int val(char c)
{
    if (c >= '0' && c <= '9')
        return (int)c - '0';
    else
        return (int)c - 'A' + 10;
}

Ответы [ 2 ]

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

Начну с очевидного: уже есть библиотечная функция, которая может преобразовывать строку, содержащую число в любой базе от (я полагаю) 2 до 36:

printf("%ld\n", strtol("1A", NULL, 20));
// Output: 30

Однако, если в рамках задания или домашнего задания использование этой и аналогичных библиотечных функций запрещено, я не буду выполнять за вас домашнюю работу, а вместо этого дам описание алгоритма высокого уровня для чтения. целое число в произвольной базе, N:

  1. Инициализировать переменную accumulator в ноль.
  2. Инициализировать переменную подсчета i в 0.
  3. Умножить accumulator на N.
  4. Получите числовое значение цифры base-N, которая в данный момент находится в str[i], и добавьте ее к accumulator (ваша функция val).
  5. Увеличение i.
  6. Если str[i] равно '\0', верните accumulator и выйдите. В противном случае перейдите к шагу 3.
0 голосов
/ 05 марта 2019

Два ключевых вопроса, которые я вижу в вашем коде:

void itov(char vigesimalStr[])
// ...
    return -1;

Функция itov() не может быть void, если она возвращает -1 при ошибке. Он также не может вернуть правильное значение в случае успеха!

for (int j = length; j >= 0; j--)

При запуске последовательности в обратном направлении вы хотите начать с length - 1, так как length сам по себе никогда не является допустимым индексом, поскольку это последний индекс плюс один.

Ниже приведена доработка вашего кода с исправленными выше проблемами и устранением других мелких проблем:

#include <stdio.h>
#include <stdlib.h>

#define BASE 20

int val(char c)
{
    if ('0' <= c && c <= '9')
        return c - '0';

    return c - 'A' + 10;
}

int itov(char vigesimalStr[])
{
    int length = 0;

    for (length = 0; vigesimalStr[length] != '\0'; length++)
    {
        // nothing to see here
    }

    int power = 1;
    int number = 0;

    for (int j = length - 1; j >= 0; j--)
    {
        int digit = val(vigesimalStr[j]);

        if (digit >= BASE)
        {
            fprintf(stderr, "Invalid Number\n");
            return -1;
        }

        number += digit * power;
        power *= BASE;
    }

    return number;
}

int main()
{
    char to_convert[20] = "1A";

    printf("%d\n", itov(to_convert));

    return 0;
}
...