【问题标题】:Converting base 20 to int将基数 20 转换为 int
【发布时间】:2019-03-05 17:56:15
【问题描述】:

我正在尝试将基数 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;
}

【问题讨论】:

  • 这是一项禁止使用strtol-family 功能的练习或家庭作业吗?如果没有,我会使用其中之一。
  • “运行中的问题”不是有效的问题描述。也请正确缩进你的代码。
  • FWIW valitov 在使用前没有原型。
  • 我在下面添加了 val 函数。你可能会看到它。我可以使用 strtol 函数,但如何像其他语言一样获取 int(c) 值。
  • power = power * base; 可以int 溢出(未定义的行为),即使num += val(vigesimalStr[j]) * power; 不会。

标签: c base


【解决方案1】:

我首先要说明的是,已经有一个库函数可以将包含(我相信)2 到 36 的任何基数的数字的字符串转换为:

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

但是,如果作为练习或家庭作业的一部分,禁止使用此库函数和类似的库函数,我将不会为您完成作业,而是会为您提供高级阅读算法的描述任意基数的整数,N:

  1. accumulator 变量初始化为零。
  2. 将计数变量i 初始化为0
  3. accumulator 乘以 N。
  4. 获取当前在str[i] 中的以N 为底的数字的数值,并将其添加到accumulator(您的val 函数)。
  5. 增加i
  6. 如果str[i]'\0',则返回accumulator 并退出。否则,请转到第 3 步。

【讨论】:

    【解决方案2】:

    我在您的代码中看到的两个关键问题:

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

    如果 itov() 函数在错误时返回 -1,则它不能是 void。成功时也无法返回正确的值!

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-18
      • 1970-01-01
      • 1970-01-01
      • 2013-08-25
      • 2018-05-11
      相关资源
      最近更新 更多