我试图将基数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到36:
printf("%ld\n", strtol("1A", NULL, 20));
// Output: 30
但是,如果作为练习或家庭作业的一部分,禁止使用此类和类似的库函数,我将不会为您做功课,但我将为您提供读取整数的高级算法的描述。任意基数,N:
accumulator
变量初始化为零。i
初始化一个计数变量0
。accumulator
。str[i]
中的base-N数字的数值,并将其添加到accumulator
(您的val
函数)。i
。str[i]
是'\0'
,返回accumulator
并退出。否则,请转到步骤3。我在您的代码中看到的两个关键问题:
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;
}