PTA——字符串转换成十进制整数(C语言)

输入一个以#结束的字符串,本题要求滤去所有的非十六进制字符(不分大小写),组成一个新的表示十六进制数字的字符串,然后将其转换为十进制数后输出。如果在第一个十六进制字符之前存在字符“-”,则代表该数是负数。

输入格式:

输入在一行中给出一个以#结束的非空字符串。

输出格式:

在一行中输出转换后的十进制数。题目保证输出在长整型范围内。

输入样例:

+-P-xf4+-1!#

输出样例:

-3905

思路:本题的要求是先定义一个以'#'结束的字符串,再去除所有与十六进制相关的字符后将其转换成十进制数,若在第一个十六进制字符前面出现了'-',则代表最终所求的十进制数为负数。

那么我们首先可以定义一个字符串,这里注意此字符串中可能会出现如空格之类的字符,所以需要用到scanf("%[^\n]s",xx);来输入字符串数组,为的是让scanf读到换行符为止,以确保能成功读入换行符前所有的字符。

此外我们还需要知道那些字符是与十六进制相关的,在十六进制中通常用'0'-'9'代表数字上的0-9,用'a' - 'f'或者'A' - 'F'代表10-15(因为题中表示不区分大小写)。所以我们可以用一个if判断句来将这三种情况用 || 连接起来。

这里要特别注意:'-'出现的位置时第一个十六进制字符前面,而不是一定要在第一个十六进制字符左边。

详细代码如下:

#include <stdio.h>
#include <stdbool.h>
int main(){
    char arr[1000];
    long long result = 0;
    long long temp;
    scanf("%[^\n]s",arr);
    bool negetive_sign = false;
    bool find_sixteen = false;// 用布尔类型来判断是否找到'-',以及十六进制字符
    for(int i = 0;arr[i] != '#';i ++){
  //如果在找到第一个十六进制字符前找到了'-',则将其变为true
        if(arr[i] == '-'){
            if(!find_sixteen){
                negetive_sign = true;
            }
            continue;
        }
        if((arr[i] >= 'A' && arr[i] <= 'F') || (arr[i] >= 'a' && arr[i] <= 'f') || (arr[i] >= '0' && arr[i] <= '9')){
            find_sixteen = true;//找到第一个十六进制字符,将其变为true
            if(arr[i] > 'A' && arr[i] <= 'Z'){
                temp = arr[i] - 'A' + 10;//将字符转换成数字
            }
            else if(arr[i] >= 'a' && arr[i] <= 'z'){
                temp = arr[i] - 'a' + 10;
            }
            else{
                temp = arr[i] - '0';
            }
            result = result * 16 + temp;//将十六进制数转换成十进制
        }
    }
    if(negetive_sign){
        result = -result;
    }
    printf("%lld",result);
    return 0;
}

逐步分析:

    for(int i = 0;arr[i] != '#';i ++){
        if(arr[i] == '-'){
            if(!find_sixteen){
                negetive_sign = true;
            }
            continue;
        }

用一个for循环,如果arr[i] 不等于'#' ,则一直执行下去,接着判断arr[i]是否是'-',如果是则进入下一个if判断句,if(!find_sixteen)的意思是如果在没有找到第一个十六进制字符之前发现了'-',则满足条件,让negetive_sign等于true。

        if((arr[i] >= 'A' && arr[i] <= 'F') || (arr[i] >= 'a' && arr[i] <= 'f') || (arr[i] >= '0' && arr[i] <= '9')){
            find_sixteen = true;
            if(arr[i] > 'A' && arr[i] <= 'Z'){
                temp = arr[i] - 'A' + 10;
            }
            else if(arr[i] >= 'a' && arr[i] <= 'z'){
                temp = arr[i] - 'a' + 10;
            }
            else{
                temp = arr[i] - '0';
            }
            result = result * 16 + temp;
        }
    }
    if(negetive_sign){
        result = -result;
    }

 用两个或运算符将三个判断十六进制字符的条件连接起来,满足其中一个即满足条件,并且令find_sixteen的值为true。接着再分别对三个条件进行判断,再将字符转换成数字。

这里需要细讲一下为什么这个操作会将字符转换成数字了,若字符是'0' - '9',则用字符减去'0'则会得到对应的数字,这个无需多说。主要是面对字符是'a' - 'f'和'A' - 'F'的情况,这两种情况思路一样就以前者为例,arr[i] - 'a'的意思其实是arr[i]与'a'在ascii骂上的相对位置,比如'b' - 'a'  = 1(由他们对应的ascii码相减所得),表示b在a的右侧,+10则将其转换成了数字,即十六进制中用b或者B表示11这个数字。

最后将答案输出即可。

本人刚学习c语言不久,如果不正确,或逻辑不通的地方还望指正,本人一定虚心学习!

谢谢大家观看!

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值