c-一个函数,用于转换非法输入的基数和错误



我编写了一个函数,可以在不同的用户指定的数字基数之间转换字符串。例如,八进制是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|%dn", 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]='';
        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"

我将如何实现返回-1和ERROR?

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

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 ... */

最新更新