一个函数,它将转换非法输入的数字基数和错误

时间:2016-05-04 20:49:52

标签: c visual-studio

我编写了一个函数,它将在不同的用户指定数字库之间转换字符串。例如,八进制是8,十进制是10.字母A到Z可以被认为是基数为26.

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<ctype.h>
    #include<math.h>
    #define MAXBUF 64

    int baseconv(char s[], int sb, char d[], int db);

    void main()
    {
        char s[MAXBUF+1], d[MAXBUF+1]; // source, destination value (as char string)
        int sb,db;                     // source, destination base
        int decval;                    // calculated decimal value
        char buf[MAXBUF+10];           // temp buffer
        char *p;                       // pointer to string

        printf("Enter src value, src base, dst base: ");
        gets(buf);
        p=strtok(buf," ,");
        while(stricmp(p,"END"))
        {
            strcpy(s,p);
            p=strtok(NULL," ,");        // or sb=atoi(strtok(NULL," ,"))
            sb=atoi(p);

            p=strtok(NULL," ,");        // or db=atoi(strtok(NULL," ,"))
            db=atoi(p);

            decval = baseconv(s,sb,d,db);

            printf("%s|%d = %d|10 = %s|%d\n", s,sb,decval,d,db);
            printf("Enter src value, src base, dst base: ");
            gets(buf);
            p=strtok(buf," , ");
        }
    }

    // actual baseconv() function 

    int baseconv(char s[], int sb, char d[], int db)
    {
        char t1[MAXBUF+10];
        char t[MAXBUF+10];
        int v=0,i=0,j=0,temp,k=0;
        while(s[i]) 
        {
            if(s[i]>=48 && s[i] < 58)    
                v = v * sb + (s[i]-48);    
            else if(s[i]>=65 && s[i]<71) 
                v = v * sb + (s[i]-65)+10;  
            else if(s[i]>=97 && s[i]<103) 
                v = v * sb + (s[i]-97)+10;
            i++;   
        }
        temp=v;
        while(v)
        {
            if(v%db+48 >= 48 && v%db+48 < 58)   
                t[j] =(v%db)+48;
            else if(v%db+55 >=65)            
                t[j] =(v%db)+55;       
            else if(v%db+87 >=97)      
                t[j] =(v%db)+87;
            v = v/db; 
            j++;
        }

        for(int n=j-1;n>=0;n--) 
        {
            t1[k]=t[n]; 
            k++;
        }
        t1[j]='\0';
        strcpy(d,t1);  
        return temp;
    }

输出就像这样 -

Enter source value, source base, dest base: 1234, 8, 16
1234|8 = 668|10 = 29C|16"

Enter source value, source base, dest base: face, 16, 8
face|16 = 64206|10 = 175316|8"

但是,我无法指定源值是否对指定的源库非法(例如1234 | 3,返回-1,并将值“ERROR”放在d []中。

输出就像这样 -

Enter source value, source base, dest base: 12345, 5, 10
12345|5 = -1|10 = ERROR|10"

我如何实现return -1和ERROR?

1 个答案:

答案 0 :(得分:0)

您可以编写一个函数,将一个字符映射到给定基数的序数值。

int map_digit_to_ordinal (int x) {
    static int map[MAX_CHAR];
    const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
    const char *p;
    if (x < 0 || x >= MAX_CAR) return -1;
    if (map['1'] == 0) {
        for (p = digits; *p; ++p) {
            map[*p] = 1 + p - digits;
            map[toupper(*p)] = 1 + p - digits;
        }
    }
    return map[x] - 1;
}

您可以使用其他功能检查数字是否在您想要的基数范围内。

int digit_in_base (int digit, int base) {
    if (base > 36) return -1;
    if (digit < base) return digit;
    return -1;
}

然后,您的转换函数可以使用此函数将潜在数字映射到正确的值。如果返回的值为-1,则您的函数应尽早返回,并将"ERROR"写入目标。

现在,您的转换函数循环可以进行适当的检查。

while(s[i]) {
    temp = map_digit_to_ordinal(s[i]);
    temp = digit_in_base(temp, sb);
    if (temp == -1) {
        strcpy(d, "ERROR");
        return -1;
    }
    v = v * sb + temp;
    i++;
}
/* rest of function ... */