'Is there a C function to convert a string with a number in base X to a string in base Y?

I am aware that strtol(hexstring, NULL, 16) will convert my string hexstring, which is hexadecimal, to a decimal. Likewise this would be the case in binary in strtol(binstring, NULL, 2). Is there a function that will do this in general? From one base to the next? If not, can someone propose the most line-efficient way?



Solution 1:[1]

OP all ready knows how to convert a string s representing base digits into an integer. Sample usage:

char *endptr;
errno = 0;
unsigned long y = strtoul(s, &endptr, base);
if (endptr == s) No_conversion();
if (errno) Handle_Overflow();
if (*endptr) Handle_TrailingText();

An easy away to convert an unsigned integer uses a compound literal for memory allocation.

How to use compound literals to fprintf() multiple formatted numbers with arbitrary bases?

If you need other methods, search on 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.

Solution 2:[2]

This is one proposition of a C99 base_convert :

#include <stdlib.h>
#include <string.h>

static char *base_convert(const char * str, const int base_in, const int base_out) {
    static const char *alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    size_t a, b, c = 1, d;
    char *s = malloc(c + 1);
    strcpy(s, "0");
    for (; *str; ++str) {
        for (a = (char*)memchr(alphabet, *str, base_out) - alphabet, b = c; b;) {
            d = ((char *) memchr(alphabet, s[--b], base_out) - alphabet) * base_in + a;
            s[b] = alphabet[d % base_out];
            a = d / base_out;
        }
        for (; a; s = realloc(s, ++c + 1), memmove(s + 1, s, c), *s = alphabet[a % base_out], a /= base_out);
    }
    return s;
}

Example usage :

#include <stdio.h>

int main() {
    const char a[] = "10000000000000000000000000000000000000000000000000000000"
                     "00000000000000000000000000000000000000000000000000000000"
                     "00000000000000000000000000000000000000000000000000000000"
                     "00000000000000000000000000000000000000000000000000000000";
    char *b = base_convert(a, 2, 10);
    puts(b);
    free(b);
}

It's magic, example output :

13479973333575319897333507543509815336818572211270286240551805124608

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2