Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am trying to solve a problem, I have one integer variable such as
unsigned int x = 456;
Now I want to decompose my integer to an array of its digits, like so:
unsigned int i[] = {4,5,6};
Then I want to convert each element of the array to a string or char.
Any ideas?
I use Avr studio
#include <stdio.h>
int main(){
unsigned int x = 456;
int len = snprintf(NULL, 0, "%u", x);
unsigned int i[len];
unsigned int wk = x;
for(int k=len-1;k>=0;--k, wk/=10)
i[k]=wk % 10;
for(int k=0;k<len;++k)
printf("%u", i[k]);
char string[len+1];
for(int k=0;k<len;++k)
sprintf(string+k, "%u", i[k]);
printf("\n%s\n", string);
return 0;
}
The easiest way to convert an integer to a string is to use a library function such as snprintf().
If you don't have the standard C library, you can use the classic remainder/division trick:
void uint_to_string(char *buf, unsigned int x, unsigned int digits)
{
buf[digits] = '\0';
while(digits > 0)
{
buf[--digits] = '0' + (x % 10);
x /= 10;
}
}
Note that the above builds the string "backwards" (right to left) since that's easiest. It will generate a 0-padded result, you can fix that by adding code to break out of the loop (after the digit is generated on the first line of the loop's body) if x == 0.
main()
{
unsigned int x = 456;
char i[3];
int j,k;
for (j=0; x!=0; j++){
i[j] = x%10 + '0';
x /= 10;
}
for (k=0; k<j; k++)
printf("%c ", i[k]);
return 0;
}
The answer to this is slightly dependent on your actual problem. Do you need the array of digits, or is this merely the intermediate step you yourself came up with to convert an unsigned integer to a string?
If all you need is the string, it would be much simpler to use a function such as sprintf or snprintf.
#include <stdio.h>
//...
unsigned int x = 456;
char digits[50]; // 50 is chosen arbitrarily
snprintf(digits, 50, "%u", x);
//...
Will yield a null-terminated string in digits that looks exactly like the string representation of x, with the caveat that if x is more than 50 digits it will just do as much as it can. (Though I'm not sure an unsigned int can even have more than 50 decimal digits off the top of my head)
If you want the char* to be exactly the correct size to hold the number, it's only a little more difficult.
#include <stdio.h>
// ...
unsigned int x = 456;
int numDigits = snprintf(NULL, 0, "%u", x); // snprintf returns the number of characters that could potentially be written.
char digits[numDigits];
sprintf(digits, "%u", x);
// ...
Without the standard library available, it gets a bit more hairy, but not unmanageably so. Unfortunately, you're going to need two passes that do almost exactly the same things: one to count the digits and one to actually assign them to your array.
int main( void ) {
// ...
unsigned int x = 456;
int numDigits = countDigits(x);
char digits[numDigits+1]; // The +1 is for null-termination
fillDigitArray(digits, x, numDigits);
// ...
}
int fillDigitArray(char *digits, int x, int numDigits) {
int i;
// This requires perhaps a little explaining
// By far the easiest way to get individual digits of a number is with
// x % 10, but this gives us the righthand-most digits
// Thus by counting DOWN, we're filling our buffer from the RIGHT
// making up for the "backwards" nature.
digits[numDigits] = 0;
for (i = numDigits-1; i >= 0; i--) {
digits[i] = '0' + (x%10);
x /= 10;
}
}
int countDigits(int x) {
// Special case
if( x == 0 ) {
return 1;
}
int numDigits;
while(x > 0) {
x /= 10;
numDigits++;
}
return numDigits;
}
Extracting it into an array of unsigned ints is similar, just make digits an unsigned int * rather than a char *, and instead of making digits[i] = '0' + x%10 make it digits[i] = x%10.
Edit: In the interest of fully explaining the example, x%10 is "x mod 10", which can roughly be stated as "give me the rightmost digit of x". x /= 10, while dividing x by 10 and overwriting x with the new value, is essentially just our way of saying "make the right-most digit of x what is currently in the 10's place".
The '0'+ x%10 part is admittedly a bit of magic. The actual ASCII character value for the number "0" isn't actually 0, but the digits 0-9 are laid out in order. So if the rightmost digits of x is 0, we get '0'+0, which is '0', and if we get the rightmost digit as 9 '0'+9' becomes '9'. Using this allows us to bypass an ugly if or switch statement to map the number to the right character.
Getting each digit is a math/logic problem. You need to use the modulus operator which gives you the remainder of the division of the operands.
#include <stdio.h>
static char digits[10];
int main(void) {
int number = 4056;
int remainder = 0;
int i = 0;
while(number > 0 && digits[i] >= 0) {
remainder = number % 10;
number /= 10;
digits[i] = 48 + remainder;
i++;
}
for(i--; i >= 0; i--) {
printf("%c", digits[i]);
}
printf("\n");
}
Related
I got large HEX string in result into int i could be more than 10 ^ 30, and I converted in hex. I need sum (3 hex string) and remove last 12 numbers.
hex example "000000000000000000000000bd4c61f945644cf099d41ab8a0ab2ac5d2533835", "000000000000000000000000000000000000000000000000f32f5908b7f3c000", "00000000000000000000000000000000000000000000000000e969cd49be4000". And I need to sum them and get result into int. Thank you
I "made" a little two functions and they work but i think could be better, and they dont convert to normal integer number
// convert hex to unsigned char decimal
unsigned char div10(unsigned char *hex, unsigned size)
{
unsigned rem = 0;
for(int i = 0; i < size; i++)
{
unsigned n = rem * 256 + hex[i];
hex[i] = n / 10;
rem = n % 10;
}
return rem;
}
unsigned char hex_to_dec_summer(char *local){
unsigned char result[32]={0};
unsigned char output[18]={};
char input[64];
strcpy(input, local);
unsigned char hexnr[sizeof(input)/2]={};
for (int i=0; i<sizeof(input)/2; i++) {
sscanf(&input[i*2], "%02xd", &hexnr[i]);
}
unsigned char hexzero[32] = {0};
unsigned i = 0;
while(memcmp(hexnr, hexzero, sizeof(hexnr)) != 0 && i < sizeof(result))
{
result[sizeof(result) - i - 1] = div10(hexnr, sizeof(hexnr));
i++;
}
printf("\n");
for(unsigned j = 0; j < sizeof output; j++)
{
output[j]=result[j];
printf("%d", output[j]);
}
output[18]='\0';
}
I know how its make in python3 -> int(hex_number, 16)/(10**12) - like that but i need it in c
The reason this sort of thing works so easily in Python is that, unusually, Python supports arbitrary-precision integers natively.
Most languages, including C, use fixed sizes for their native types. To perform arbitrary-precision arithmetic, you generally need a separate library, such as GMP.
Here is a basic example of using GMP to solve your problem:
#include <stdio.h>
#include <gmp.h>
char *inputs[] = {
"000000000000000000000000bd4c61f945644cf099d41ab8a0ab2ac5d2533835",
"000000000000000000000000000000000000000000000000f32f5908b7f3c000",
"00000000000000000000000000000000000000000000000000e969cd49be4000"
};
int main()
{
char outstr[100];
mpz_t x; mpz_init(x);
mpz_t y; mpz_init(y);
mpz_t sum; mpz_init(sum);
mpz_t ten; mpz_init_set_si(ten, 10);
mpz_t fac; mpz_init(fac);
mpz_pow_ui(fac, ten, 12); /* fac = 10**12 */
int i;
for(i = 0; i < 3; i++) {
mpz_set_str(x, inputs[i], 16);
mpz_tdiv_q(y, x, fac);
mpz_add(sum, sum, y); /* sum += x / fac */
}
printf("%s\n", mpz_get_str(outstr, 10, sum));
}
The code is a bit verbose, because arbitrary-precision integers (that is, variables of type mpz_t) have nontrivial memory allocation requirements, and everything you do with them requires explicit function calls. (Working with extended types like this would be considerably more convenient in a language with good support for object-oriented programming, like C++.)
To compile this, you'll need to have GMP installed. On my machine, I used
cc testprog.c -lgmp
When run, this program prints
1080702647035076263416932216315997551
Or, if I changed 10 to 16 in the last line, it would print d022c1183a2720991b1fea332a6d6f.
It will make a slight difference whether you divide by 1012 and then sum, or sum and then divide. To sum and then divide, you could get rid of the line mpz_tdiv_q(y, x, fac) inside the loop, change mpz_add(sum, sum, y) to mpz_add(sum, sum, x), and add the line
mpz_tdiv_q(sum, sum, fac);
outside the loop, just before printing.
It's fairly straight forward to add up the (in this case hex) digits of two strings.
This doesn't try to be "optimal", but it does give a sum (as a string of hex digits). vals[0] acts as the accumulator.
When OP clarifies what is meant by "I need sum (3 hex string) and remove last 12 numbers", this answer could be extended.
If more speed is needed, the accumulator could be allocated and used as an array of uint8_t's (saving converting back to ASCII hex until a final total is available.) Also the LUT to convert ASCII hex to '0-F' could be 'binary' (not requiring the subtraction of ASCII character values.)
Anyway...
#include <stdio.h>
char *vals[] = {
"000000000000000000000000bd4c61f945644cf099d41ab8a0ab2ac5d2533835",
"000000000000000000000000000000000000000000000000f32f5908b7f3c000",
"00000000000000000000000000000000000000000000000000e969cd49be4000",
};
char *frmHex =
"................................................0000000000......"
".777777..........................WWWWWW.........................";
char *tohex = "0123456789ABCDEF";
void addTo( char *p0, char *p1 ) {
printf( " %s\n+ %s\n", p0, p1 );
char *px = p0 + strlen( p0 ) - 1;
char *py = p1 + strlen( p1 ) - 1;
for( int carry = 0; px >= p0 && py >= p1; px--, py-- ) {
int val = *px - frmHex[ *px ] + *py - frmHex[ *py ] + carry;
carry = val / 0x10; *px = tohex[ val % 0x10 ];
}
printf( "= %s\n\n", p0 );
}
int main() {
addTo( vals[ 0 ], vals[ 1 ] );
addTo( vals[ 0 ], vals[ 2 ] );
return 0;
}
Output
000000000000000000000000bd4c61f945644cf099d41ab8a0ab2ac5d2533835
+ 000000000000000000000000000000000000000000000000f32f5908b7f3c000
= 000000000000000000000000BD4C61F945644CF099D41AB993DA83CE8A46F835
000000000000000000000000BD4C61F945644CF099D41AB993DA83CE8A46F835
+ 00000000000000000000000000000000000000000000000000e969cd49be4000
= 000000000000000000000000BD4C61F945644CF099D41AB994C3ED9BD4053835
If this were to progress (and use binary accumulators), 'compaction' after summing would quickly lead into integer division (that could be done simply with shifting and repeated subtraction.) Anyway...
I have written a C program which uses two different algorithms to convert a string constant representing a numeric value to its integer value. For some reasons, the first algorithm, atoi(), doesn't execute properly on large values, while the second algorithm, atoi_imp(), works fine. Is this an optimization issue or some other error? The problem is that the first function makes the program's process to terminate with an error.
#include <stdio.h>
#include <string.h>
unsigned long long int atoi(const char[]);
unsigned long long int atoi_imp(const char[]);
int main(void) {
printf("%llu\n", atoi("9417820179"));
printf("%llu\n", atoi_imp("9417820179"));
return 0;
}
unsigned long long int atoi(const char str[]) {
unsigned long long int i, j, power, num = 0;
for (i = strlen(str) - 1; i >= 0; --i) {
power = 1;
for (j = 0; j < strlen(str) - i - 1; ++j) {
power *= 10;
}
num += (str[i] - '0') * power;
}
return num;
}
unsigned long long int atoi_imp(const char str[]) {
unsigned long long int i, num = 0;
for (i = 0; str[i] >= '0' && str[i] <= '9'; ++i) {
num = num * 10 + (str[i] - '0');
}
return num;
}
atoi is part of C standard library, with signature int atoi(const char *);.
You are declaring that a function with that name exists, but give it different return type. Note that in C, function name is the only thing that matters, and the toolchain can only trust what you tell in the source code. If you lie to the compiler, like here, all bets are off.
You should select different name for your own implementation to avoid issues.
As researched by #pmg, C standard (link to C99.7.1.3) says, using names from C standard library for your own global symbols (functions or global variables) is explicitly Undefined Behavior. Beware of nasal demons!
Ok there is at least one problem with your function atoi.
You are looping down on an unsigned value and check if its bigger equal zero, which should be an underflow.
The most easy fix is index shifting i.e.:
unsigned long long int my_atoi(const char str[]) {
unsigned long long int i, j, power, num = 0;
for (i = strlen(str); i != 0; --i) {
power = 1;
for (j = 0; j < strlen(str) - i; ++j) {
power *= 10;
}
num += (str[i-1] - '0') * power;
}
return num;
}
Too late, but may help. I did for base 10, in case you change the base you need to take care about how to compute the digit 0, in *p-'0'.
I would use the Horner's rule to compute the value.
#include <stdio.h>
void main(void)
{
char *a = "5363", *p = a;
int unsigned base = 10;
long unsigned x = 0;
while(*p) {
x*=base;
x+=(*p-'0');
p++;
}
printf("%lu\n", x);
}
Your function has an infinite loop: as i is unsigned, i >= 0 is always true.
It can be improved in different ways:
you should compute the length of str just once. strlen() is not cheap, it must scan the string until it finds the null terminator. The compiler is not always capable of optimizing away redundant calls for the same argument.
power could be computed incrementally, avoiding the need for a nested loop.
you should not use the name atoi as it is a standard function in the C library. Unless you implement its specification exactly and correctly, you should use a different name.
Here is a corrected and improved version:
unsigned long long int atoi_power(const char str[]) {
size_t i, len = strlen(str);
unsigned long long int power = 1, num = 0;
for (i = len; i-- > 0; ) {
num += (str[i] - '0') * power;
power *= 10;
}
return num;
}
Modified this way, the function should have a similar performance as the atoi_imp version. Note however that they do not implement the same semantics. atoi_pow must be given a string of digits, whereas atoi_imp can have trailing characters.
As a matter of fact neither atoi_imp nor atoi_pow implement the specification of atoi extended to handle larger unsigned integers:
atoi ignored any leading white space characters,
atoi accepts an optional sign, either '+' or '-'.
atoi consumes all following decimal digits, the behavior on overflow is undefined.
atoi ignores and trailing characters that are not decimal digits.
Given these semantics, the natural implementation or atoi is that of atoi_imp with extra tests. Note that even strtoull(), which you could use to implement your function handles white space and an optional sign, although the conversion of negative values may give surprising results.
I've been trying to print out the Binary representation of a long long integer using C Programming
My code is
#include<stdio.h>
#include <stdlib.h>
#include<limits.h>
int main()
{
long long number, binaryRepresentation = 0, baseOfOne = 1, remainder;
scanf("%lld", &number);
while(number > 0) {
remainder = number % 2;
binaryRepresentation = binaryRepresentation + remainder * baseOfOne;
baseOfOne *= 10;
number = number / 2;
}
printf("%lld\n", binaryRepresentation);
}
The above code works fine when I provide an input of 5 and fails when the number is 9223372036854775807 (0x7FFFFFFFFFFFFFFF).
1.Test Case
5
101
2.Test Case
9223372036854775807
-1024819115206086201
Using a denary number to represent binary digits never ends particularly well: you'll be vulnerable to overflow for a surprisingly small input, and all subsequent arithmetic operations will be meaningless.
Another approach is to print the numbers out as you go, but using a recursive technique so you print the numbers in the reverse order to which they are processed:
#include <stdio.h>
unsigned long long output(unsigned long long n)
{
unsigned long long m = n ? output(n / 2) : 0;
printf("%d", (int)(n % 2));
return m;
}
int main()
{
unsigned long long number = 9223372036854775807;
output(number);
printf("\n");
}
Output:
0111111111111111111111111111111111111111111111111111111111111111
I've also changed the type to unsigned long long which has a better defined bit pattern, and % does strange things for negative numbers anyway.
Really though, all I'm doing here is abusing the stack as a way of storing what is really an array of zeros and ones.
As Bathsheba's answer states, you need more space than is
available if you use a decimal number to represent a bit sequence like that.
Since you intend to print the result, it's best to do that one bit at a time. We can do this by creating a mask with only the highest bit set. The magic to create this for any type is to complement a zero of that type to get an "all ones" number; we then subtract half of that (i.e. 1111.... - 0111....) to get only a single bit. We can then shift it rightwards along the number to determine the state of each bit in turn.
Here's a re-worked version using that logic, with the following other changes:
I use a separate function, returning (like printf) the number of characters printed.
I accept an unsigned value, as we were ignoring negative values anyway.
I process arguments from the command line - I tend to find that more convenient that having to type stuff on stdin.
#include <stdio.h>
#include <stdlib.h>
int print_binary(unsigned long long n)
{
int printed = 0;
/* ~ZERO - ~ZERO/2 is the value 1000... of ZERO's type */
for (unsigned long long mask = ~0ull - ~0ull/2; mask; mask /= 2) {
if (putc(n & mask ? '1' : '0', stdout) < 0)
return EOF;
else
++printed;
}
return printed;
}
int main(int argc, char **argv)
{
for (int i = 1; i < argc; ++i) {
print_binary(strtoull(argv[i], 0, 10));
puts("");
}
}
Exercises for the reader:
Avoid printing leading zeros (hint: either keep a boolean flag that indicates you've seen the first 1, or have a separate loop to shift the mask before printing). Don't forget to check that print_binary(0) still produces output!
Check for errors when using strtoull to convert the input values from decimal strings.
Adapt the function to write to a character array instead of stdout.
Just to spell out some of the comments, the simplest thing to do is use a char array to hold the binary digits. Also, when dealing with bits, the bit-wise operators are a little more clear. Otherwise, I've kept your basic code structure.
int main()
{
char bits[64];
int i = 0;
unsigned long long number; // note the "unsigned" type here which makes more sense
scanf("%lld", &number);
while (number > 0) {
bits[i++] = number & 1; // get the current bit
number >>= 1; // shift number right by 1 bit (divide by 2)
}
if ( i == 0 ) // The original number was 0!
printf("0");
for ( ; i > 0; i-- )
printf("%d", bits[i]); // or... putchar('0' + bits[i])
printf("\n");
}
I am not sure what you really want to achieve, but here is some code that prints the binary representation of a number (change the typedef to the integral type you want):
typedef int shift_t;
#define NBITS (sizeof(shift_t)*8)
void printnum(shift_t num, int nbits)
{
int k= (num&(1LL<<nbits))?1:0;
printf("%d",k);
if (nbits) printnum(num,nbits-1);
}
void test(void)
{
shift_t l;
l= -1;
printnum(l,NBITS-1);
printf("\n");
l= (1<<(NBITS-2));
printnum(l,NBITS-1);
printf("\n");
l= 5;
printnum(l,NBITS-1);
printf("\n");
}
If you don't mind to print the digits separately, you could use the following approach:
#include<stdio.h>
#include <stdlib.h>
#include<limits.h>
void bindigit(long long num);
int main()
{
long long number, binaryRepresentation = 0, baseOfOne = 1, remainder;
scanf("%lld", &number);
bindigit(number);
printf("\n");
}
void bindigit(long long num) {
int remainder;
if (num < 2LL) {
printf("%d",(int)num);
} else {
remainder = num % 2;
bindigit(num/2);
printf("%d",remainder);
}
}
Finally I tried a code myself with idea from your codes which worked,
#include<stdio.h>
#include<stdlib.h>
int main() {
unsigned long long number;
int binaryRepresentation[70], remainder, counter, count = 0;
scanf("%llu", &number);
while(number > 0) {
remainder = number % 2;
binaryRepresentation[count++] = remainder;
number = number / 2;
}
for(counter = count-1; counter >= 0; counter--) {
printf("%d", binaryRepresentation[counter]);
}
}
I have to write a C program for one of my classes that converts a given binary number to decimal. My program works for smaller inputs, but not for larger ones. I believe this may be due to the conversion specifier I am using for scanf() but I am not positive. My code is below
#include<stdio.h>
#include<math.h>
int main(void)
{
unsigned long inputNum = 0;
int currentBinary = 0;
int count = 0;
float decimalNumber = 0;
printf( "Input a binary number: " );
scanf( "%lu", &inputNum );
while (inputNum != 0)
{
currentBinary = inputNum % 10;
inputNum = inputNum / 10;
printf("%d\t%d\n", currentBinary, inputNum);
decimalNumber += currentBinary * pow(2, count);
++count;
}
printf("Decimal conversion: %.0f", decimalNumber);
return 0;
}
Running with a small binary number:
Input a binary number: 1011
1 101
1 10
0 1
1 0
Decimal conversion: 11
Running with a larger binary number:
Input a binary number: 1000100011111000
2 399133551
1 39913355
5 3991335
5 399133
3 39913
3 3991
1 399
9 39
9 3
3 0
Decimal conversion: 5264
"1000100011111000" is a 20 digit number. Certainly unsigned long is too small on your platform.
unsigned long is good - up to at least 10 digits.1
unsigned long long is better - up to at least 20 digits.1
To get past that:
Below is an any size conversion by reading 1 char at a time and forming an unbounded string.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// Double the decimal form of string: "512" --> "1024"
char *sdouble(char *s, size_t *len, int carry) {
size_t i = *len;
while (i > 0) {
i--;
int sum = (s[i] - '0')*2 + carry;
s[i] = sum%10 + '0';
carry = sum/10;
}
if (carry) {
(*len)++;
s = realloc(s, *len + 1); // TBD OOM check
memmove(&s[1], s, *len);
s[0] = carry + '0';
}
return s;
}
int main(void) {
int ch;
size_t len = 1;
char *s = malloc(len + 1); // TBD OOM check
strcpy(s, "0");
while ((ch = fgetc(stdin)) >= '0' && ch <= '1') {
s = sdouble(s, &len, ch - '0');
}
puts(s);
free(s);
return 0;
}
100 digits
1111111111000000000011111111110000000000111111111100000000001111111111000000000011111111110000000000
1266413867935323811836706421760
1 When the lead digit is 0 or 1.
When you do this for a large number inputNum
currentBinary = inputNum % 10;
its top portion gets "sliced off" on conversion to int. If you would like to stay within the bounds of an unsigned long, switch currentBinary to unsigned long as well, and use an unsigned long format specifier in printf. Moreover, unsigned long may not be sufficiently large on many platforms, so you need to use unsigned long long.
Demo.
Better yet, switch to reading the input in a string, validating it to be zeros and ones (you have to do that anyway) and do the conversion in a cleaner character-by-character way. This would let you go beyond the 64-bit of 19 binary digits to have a full-scale int input.
unsigned long supports a maximum number of 4294967295, which means in the process of scanf( "%lu", &inputNum ); you've sliced the decimal number 1000100011111000 to a 32-bit unsigned long number.
I think scanf inputNum to a string would help a lot. In the while loop condition check if the string is empty now, and in the loop body get the last char of the string, detect if it's an '1' of a '0', and then calculate the binary number using this info.
I was tasked with writing a binary to decimal converted with taking larger binary inputs, but using embedded C programming in which we are not allowed to use library functions such as strlen. I found a simpler way to write this conversion tool using C, with both strlen, and also sizeof, as shown in the code below. Hope this helps. As you can see, strlen is commented out but either approach works fine. Sizeof just accounts for the 0 elecment in the array and that is why sizeof (number) -1 is used. Cheers!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char number[] = "100111111111111111111111";
int binToDec(char *);
int main()
{
printf("Output: %d", binToDec(&number));
}
int binToDec(char *n)
{
char *num = n;
int decimal_value = 0;
int base = 1;
int i;
int len = sizeof(number)-1;
//int len = strlen(number);
for (i=len-1; i>=0; i--)
{
if (num[i] == '1')
decimal_value += base;
base = base * 2;
}
return decimal_value;
}
For example take 123 and put it into an array where that is a[3] = {1, 2, 3}?
Without converting it to a string and iterating over it.
You can get the decimal digits of a number by using integer division and modulo.
//Pseudo code
int[MAX_SIZE] result;
int index = 0;
while (workingNumber > 0)
{
digit = workingNumber % 10;
result[index] = digit;
workingNumber = workingNumber / 10; //Must be integer division
index++;
}
#include <math.h>
...
int number = 5841;
int size = log10(number) + 1;
int arr[size];
int i = size;
while(i >= 0)
{
arr[--i] = number % 10;
number /= 10;
}
First, keep in mind that in C the only real difference between "array of char" and "string" is to be a string, you put a NUL-terminator at the end of the array of char.
Assuming you wanted (for example) to create an array of int (or long, or something else other than char), you'd typically take the remainder when dividing by 10 and convert it to a digit by adding '0'. Then divide the number by 10 and repeat until it's reduced to zero. That creates the numbers from least to most significant, so you normally deposit them at the end of the array and work backward toward the beginning.
#include <stdio.h>
#include <math.h>
#define LEN 3
int main(int argc,char* argv[])
{
int i = 123;
int a[LEN];
int digit;
int idx = log10(i);
do {
digit = i % 10;
i /= 10;
a[idx--] = digit;
} while (i != 0);
printf("a: { %d, %d, %d }\n", a[0], a[1], a[2]);
return 0;
}