将十进制转换为任意基数(从 2 到 36)的 C 代码

C code for converting decimal to any base (from 2 to 36)

我最近刚开始学习C。我写了一个很短的程序,可以在十进制和二进制之间进行转换。我想尝试编写一个在十进制和任何基数(直到 36)之间进行转换的代码。但是,我的代码只是打印出垃圾。

#include <stdio.h>
#include <string.h>

void printBase(int n, int k, int i, char a[])
{
    int placeholder;
    if (n != 0)
    {
        //return n % 2 + 10 * printBinary(n / 2);
        placeholder=(char)(n%k);
        if(placeholder>=10)
        {
            a[i] = (char)(placeholder - 10) + 'A';
        } else {
            a[i] = (char)placeholder;
        }
        i++;
        printBase(n/2, k, i, a);
    }
    for (i=0; a[i]!='[=10=]'; i++)
    {
        printf("%c", a[i]);
    }
    return;
}

void reverse(char fromStr[], char toStr[])
{
    int i, j=0;
    i=getchar();
    for (i=0; fromStr[i]!='[=10=]'; i++)
    {
        j++;
    }
    i=0;
    while (j>=0)
    {
        toStr[i]=fromStr[j];
        i++;
        j--;
    }
    printf("%s", toStr);
}

int main()
{
    int n, k;
    char a[81], b[81];
    setvbuf(stdout, NULL, _IONBF, 0);
    printf("Enter a deicmal number you want to convert to binary: ");
    scanf("%i", &n);
    fflush(stdout);
    printf("Enter a base: ");
    scanf("%i", &k);
    printBase(n, k, 0, a);
    //printf("%s", a);
    //reverse(a, b);
    return 0;
}

我认为问题出在我的反向函数上,但它在这段代码之外工作正常。即使当我在 printBase 函数中打印出字符串 a 时,它也会打印出垃圾。这里有什么问题?

#define c ('A' - 10)


int n = 4564567; // any number
int b = 16; // any base

int tmp = n < 0 ? -n : n;
int i = 0;

while (tmp)
{
    tmp /= b;
    ++i; // you need to calculate how long will be the number
}

while (i--)
{
    a[i] = n % b + ((n % b < 10) ? '0' : c); // you have to check if the remaining is below 10 or not. That is very important
    n /= b;
}

我想你忘记在 else 的情况下添加 '0'

改编自旧源文件https://github.com/agavrel/42-ft_printf/blob/master/srcs/pf_number.c

根据您的代码,下面的代码可以满足您的要求。它在 a 中放置一个 reverse 转换,仍然必须向后打印:

void convertBase(int n, int k, char a[])
{
    int j, i=0, sign= 0;
    if (n==0) a[i++]='0';
    if (n<0 ) {sign= -1; n= -n;}
    while (n>0) {
        j= n%k;
        if (j<10)
            a[i]= j+'0';
        else
            a[i]= j+'A';
        n= n/k;
        i++;
    }
    if (sign== -1) a[i++]= '-';
    a[i]= 0;
}

这里是还原:

void revStr(char *s)
{
    char c;
    int i=0, j=0;
    while (s[i]) i++; i--;
    while (i>j) {
        c= s[j];
        s[j]=s[i];
        s[i]= c;
        i--; j++;
    }
}

使用 itoa

的一些通用实现
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>

static const char* DIGISTS = "0123456789ABCDEFGHIKLMNOPQRSTVXYZ";

void itoa(long long i, unsigned char radix, char* to) {
    char *s = to + 65;
    char sign;
    unsigned len;
    if(i < 0) {
        sign = 1;
        len = 2;
    } else {
        sign = 0;
        len = 1;
    }
    *s = '[=10=]';
    do {
        *(--s)= * ( DIGISTS + abs(i % radix) );
        i /= radix;
        ++len;
    } while(i != 0);
    if(sign)
        *(--s) = '-';
    memmove( to, s, len );
}

int main(int argc, const char** argv)
{
    char a[65];
    itoa( LLONG_MAX, 2, a);
    printf("binary: %s \n", a);
    itoa(12345, 10, a);
    printf("digit: %s \n", a);
    itoa(64018, 16, a);
    printf("hex : 0x%s \n", a);
    itoa(-24, 24, a);
    printf("base 24 : base24x%s \n", a);
    itoa(LLONG_MAX, 36, a);
    printf("base 36 : base36x%s \n", a);
    return 0;
}

反转数组的替代方法是使用递归。

由于某些整数类型的位数从来没有这么大,因此递归不会过多。

下面使用 do {} while 循环来避免 printBase(0) 的特殊情况。
它还在 printBase_helper() 中使用负值,其中 /,% 在 C99 中定义明确。这避免了代码的未定义行为,例如 n = -nn == INT_MIN.

void printBase_helper(int neg, int base) {
  if (neg <= -base) {
    printBase_helper(neg / base, base);
    neg %= base;
  }
  putchar("0123456789ABCDEFGHIJKLMONOPQSTUVWXYZ"[-neg]);
}

void printBase(int n, int base) {
  if (n < 0) {
    putchar('-');
  } else {
    n = -n;
  }
  printBase_helper(n, base);
}

测试码

int main(void) {
  int value[] = {0, 1, -1, 10, INT_MAX, INT_MIN};
  int base[] = {10, 2, 36};
  for (unsigned v = 0; v < sizeof value / sizeof value[0]; v++) {
    for (unsigned b = 0; b < sizeof base / sizeof base[0]; b++) {
      printf("Base %2d, value %11d, --> base %2d, value ", 10, value[v], base[b]);
      printBase(value[v], base[b]);
      printf("\n");
    }
  }
  return 0;
}

输出

Base 10, value           0, --> base 10, value 0
Base 10, value           0, --> base  2, value 0
Base 10, value           0, --> base 36, value 0
Base 10, value           1, --> base 10, value 1
Base 10, value           1, --> base  2, value 1
Base 10, value           1, --> base 36, value 1
Base 10, value          -1, --> base 10, value -1
Base 10, value          -1, --> base  2, value -1
Base 10, value          -1, --> base 36, value -1
Base 10, value          10, --> base 10, value 10
Base 10, value          10, --> base  2, value 1010
Base 10, value          10, --> base 36, value A
Base 10, value  2147483647, --> base 10, value 2147483647
Base 10, value  2147483647, --> base  2, value 1111111111111111111111111111111
Base 10, value  2147483647, --> base 36, value ZIK0ZJ
Base 10, value -2147483648, --> base 10, value -2147483648
Base 10, value -2147483648, --> base  2, value -10000000000000000000000000000000
Base 10, value -2147483648, --> base 36, value -ZIK0ZK

我不知道我自己的问题的答案应该贴在下面,抱歉! 但这里是我自己编写的代码,如果它对任何人有帮助的话:

#include <stdio.h>
#include <string.h>

void printBinary(int n, int k, int i, char a[])
{
    int placeholder;
    if (n != 0)
    {
        placeholder=(n%k);
        if(placeholder>=10)
        {
            a[i] = (placeholder - 10) + 'A';
        } else if(placeholder>=0 && placeholder<=9){
            a[i] = placeholder + '0';
        }
        i++;
        a[i]='[=10=]';
        printBinary(n/k, k, i, a);
    }
    return;
}

int main()
{
    int n, k;
    char a[81], b[81];
    setvbuf(stdout, NULL, _IONBF, 0);
    printf("Enter a deicmal number you want to convert to binary: ");
    scanf("%i", &n);
    fflush(stdout);
    printf("Enter a base: ");
    scanf("%i", &k);
    printBinary(n, k, 0, a);
    n=strlen(a);
    k=0;
    n--;
    while (n>=0)
    {
        b[k]=a[n];
        n--;
        k++;
    }
    b[k]='[=10=]';
    printf("%s", b);
    return 0;
}
    Try this one.

#include<stdio.h>
    int main()
    {
        int n,b,t1,i=0;
        float t2,t3,t4;
        int a[10];
        scanf("%d%d",&n,&b);
        for( i=0; n!=0; i++)
        {
            t1=n/b;
            t2=(float)n/b;
            t3=(float)t2-t1;
            t1=t3*b;
            t2=(float)t3*b;
            t4=(float)t2-t1;
            if(t4>=0.5)
            {
                a[i]=t3*b+1;

            }
            else
            {
                a[i]=t3*b;
            }
            n=n/b;
        }
        for(int j=i; j>0; j--)
        {
            printf("%d",a[j-1]);
        }

    return 0;
    }