从任何基数转换为十进制和区分大小写

问题描述

我正在使用以下门户来验证我的代码的结果(同样来自网络):

RapidTables BaseConverter

我的代码如下图:

// C program to convert a number from any base 
// to decimal 
#include <stdio.h> 
#include <string.h> 
  
// To return value of a char. For example,2 is 
// returned for '2'.  10 is returned for 'A',11 
// for 'B' 
int val(char c) 
{ 
    if (c >= '0' && c <= '9') 
        return (int)c - '0'; 
    else
        return (int)c - 'A' + 10; 
} 
  
// Function to convert a number from given base 'b' 
// to decimal 
int toDeci(char *str,int base) 
{ 
    int len = strlen(str); 
    int power = 1; // Initialize power of base 
    int num = 0;  // Initialize result 
    int i; 
  
    // Decimal equivalent is str[len-1]*1 + 
    // str[len-1]*base + str[len-1]*(base^2) + ... 
    for (i = len - 1; i >= 0; i--) 
    { 
        // A digit in input number must be 
        // less than number's base 
        if (val(str[i]) >= base) 
        { 
           printf("Invalid Number\n"); 
           return -1; 
        } 
  
        num += val(str[i]) * power; 
        power = power * base; 
    } 
  
    return num; 
} 
  
// Driver code 
int main() 
{ 
    char str[] = "25a"; 
    int base = 36; 
    printf("Decimal equivalent of %s in base %d is " " %d ",str,base,toDeci(str,base)); 
    return 0; 
}

main() 中所示,如果对 str[] 使用值“25a”,我会得到以下输出:

Invalid Number
Decimal equivalent of 25a in base 36 is  -1

但是,如果我将 str[] 的值更改为“25A”,则会得到以下输出:

Decimal equivalent of 25A in base 36 is  2782

使用我在上面提供的用于结果验证的门户链接,我获得了两个值的最后一个结果。

所以我的问题是,如何修改我的代码以进行相应的更改?

TIA

维诺德

解决方法

为什么不使用 strtoll() 函数:

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

int main()
{
    char str[] = "25a";
    int base = 36;
    unsigned long long todeci;

    todeci = strtoll(str,(char **)NULL,base);
    printf("Decimal equivalent of %s in base %d is %lld\n",str,base,todeci);
    return 0;
}

输出:

Decimal equivalent of 25a in base 36 is 2782
,

如果您不能或不想更改函数签名或使用适当的库函数来执行转换,对 val 函数的简单更改将允许代码也管理小写.

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

对另一个函数稍作改动(使用 Horner 方法计算多项式),我们也可以避免调用 strlen

int toDeci(char *str,int base) 
{ 
    unsigned long long int num = 0;
    
    while( *str != '\0' )
    {
        int digit = val(*str);
        if ( digit == -1  ||  digit >= base )
        {
            printf("Invalid digit.\n");
            return -1;
        }
        unsigned long long int n = num * base + digit;
        if ( n < num )
        {
            printf("The number is too big.\n");
            return -1;
        }
        num = n;
        ++str;
    }
    if ( num > INT_MAX )  // You'll have to include <limits.h>
    {
        printf("The number is too big to fit into an int.\n");
        return -1;
    }
    return num; 
}

请注意,此代码仍然无法处理负数或前缀,例如 0 表示八进制数和 0x 表示十六进制数。错误检查也遵循 OP 的选择(出现问题时返回 -1),需要重新考虑。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...