I am trying to convert an integer number in C into an array containing each of that number's digits
i.e. if I have
int number = 5400
how can I get to
int numberArray[4]
where
numberArray[0] = 0;
numberArray[1] = 0;
numberArray[2] = 4;
numberArray[3] = 5;
Any suggestions gratefully received.
This would work for numbers >= 0
#include <math.h>
char * convertNumberIntoArray(unsigned int number) {
int length = (int)floor(log10((float)number)) + 1;
char * arr = new char[length];
int i = 0;
do {
arr[i] = number % 10;
number /= 10;
i++;
} while (number != 0);
return arr;
}
EDIT: Just a little bit more C style but more cryptic.
#include <math.h>
char * convertNumberIntoArray(unsigned int number) {
unsigned int length = (int)(log10((float)number)) + 1;
char * arr = (char *) malloc(length * sizeof(char)), * curr = arr;
do {
*curr++ = number % 10;
number /= 10;
} while (number != 0);
return arr;
}
Hint: Take a look at this earlier question "Sum of digits in C#". It explains how to extract the digits in the number using several methods, some relevant in C.
From Greg Hewgill's answer:
/* count number of digits */
int c = 0; /* digit position */
int n = number;
while (n != 0)
{
n /= 10;
c++;
}
int numberArray[c];
c = 0;
n = number;
/* extract each digit */
while (n != 0)
{
numberArray[c] = n % 10;
n /= 10;
c++;
}
You could calculate the number of digits in an integer with logarithm rather than a loop. Thus,
int * toArray(int number)
{
int n = log10(number) + 1;
int i;
int *numberArray = calloc(n, sizeof(int));
for ( i = 0; i < n; ++i, number /= 10 )
{
numberArray[i] = number % 10;
}
return numberArray;
}
Try this,
void initialise_array(int *a, int size, int num) {
for (int i = 0; i < size; ++i, num /= 10)
a[(size - 1) - i] = num % 10;
}
If you need to take negative numbers into account, you might need some extra logic. In fact, when playing around with arrays you don't know the size of upfront, you may want to do some more safety checking, and adding an API for handling the structure of the data is quite handy too.
// returns the number of digits converted
// stores the digits in reverse order (smalles digit first)
// precondition: outputdigits is big enough to store all digits.
//
int convert( int number, int* outputdigits, int* signdigit ) {
int* workingdigits = outputdigits;
int sign = 1;
if( number < 0 ) { *signdigit = -1; number *= -1; }
++workingdigits;
for ( ; number > 0; ++ workingdigits ) {
*workingdigits = number % 10;
number = number / 10;
}
return workingdigits - outputdigits;
}
void printdigits( int* digits, int size, int signdigit ) {
if( signdigit < 0 ) printf( "-" );
for( int* digit = digits+size-1; digit >= digits; --digit ){
printf( "%d", *digit );
}
}
int main() {
int digits[10];
int signdigit;
printdigits( digits, convert( 10, digits, &signdigit ), signdigit );
printdigits( digits, convert( -10, digits, &signdigit ), signdigit );
printdigits( digits, convert( 1005, digits, &signdigit ), signdigit );
}
#include <stdio.h>
#include <string.h>
int main(void)
{
int i, inputNumber;
char* charArray;
printf("\nEnter number: ");
scanf("%d", &inputNumber);
/* converts int to print buffer which is char array */
sprintf(charArray, "%d", inputNumber);
int size = strlen(charArray);
int intArray[size];
for (i = 0; i < size; i++)
{
intArray[i] = charArray[i] - '0';
}
return 0;
}
C code:
/* one decimal digit takes a few more than 3 bits. (2^3=8, 2^4=16) */
int digits[(sizeof (int) * CHAR_BIT) / 3 + 1],
*digitsp = digits;
do {
*digitsp++ = number % 10;
number /= 10;
} while(number > 0);
You will see how many digits you converted by taking the difference
digitsp - digits
If you want to put it into a function:
#define MIN_DIGITS_IN_INT ((sizeof (int) * CHAR_BIT) / 3 + 1)
int to_array(int number, int *digits) {
int *digitsp = digits;
do {
*digitsp++ = number % 10;
number /= 10;
} while(number > 0);
return digitsp - digits;
}
int main() {
int number = rand();
int digits[MIN_DIGITS_IN_INT];
int n = to_array(number, digits);
/* test whether we're right */
while(n-- > 0)
printf("%d", digits[n]);
}
printf(" = %d\n", number);
}
I prefer automatic arrays to dynamic memory allocation in this case, since it's easier to do it right and not leak accidentally.
using vadim's code, I came up with this test program:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
char * convertNumberIntoArray(unsigned int number) {
unsigned int length = (int)(log10((float)number)) + 1;
char * arr = (char *) malloc(length * sizeof(char)), * curr = arr;
do {
*curr++ = number % 10;
number /= 10;
} while (number != 0);
return arr;
}
int main(void)
{
int InputNumber;
int arr[5];
printf("enter number: \n");
scanf("%d", &InputNumber);
convertNumberIntoArray(InputNumber);
printf("The number components are: %d %d %d\n", arr[0],arr[1],arr[2]);
system("PAUSE");
return 0;
}
but the output is garbage. Can anyone advise if I have done something stupid here?
/***** output *****/
enter number:
501
The number components are: 2009291924 2009145456 -1
Press any key to continue . . .
--dave
Related
How do I store different digits of an integer in any array
like 1234 to {1,2,3,4}
It can be done using char str[]="1234"; printf("%c",str[0];
but how to do it without using string and in integer itself
Here's a snippet that creates an array of digits and prints them out:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
// Print digits 1 by 1
void numToDigits (int number, int base) {
int i;
int n_digits = (int)ceil(log(number+1) / log(base));
printf("%d digits\n", n_digits);
int * digits = calloc(n_digits, sizeof(int));
for (i=0; i<n_digits; ++i) {
digits[i] = number % base;
number /= base;
}
// digits[0] is the 1's place, so print them starting from the largest index
for (i=n_digits-1; i>=0; --i) {
printf("%d", digits[i]);
}
printf("\n");
free(digits);
}
You'll likely want to modify this, but I think it exposes all the important ideas. Don't forget to add -lm when you compile to include math libraries needed for log and ceil. Also note that the printing code isn't made to work with bases larger than 10.
Here's one method, more or less:
get the log10() of the integer to determine its 'size'
take the floor() of that to get exponent (number of digits - 1)
then calculate the highest divider with (int)pow(10, exponent)
finally have a for-loop:
int value = 1234; // Your value to split up in digits.
for (int d = divider; divider > 0; divider /= 10)
{
int digit = value / d;
value = value / 10;
// Store digit in array
}
I leave the details for you to fill in.
Carson had a similar idea which nicely avoids the use of pow()
If your compiler supports variable length arrays then you can use the approach shown in the demonstration program below
#include <stdio.h>
enum { Base = 10 };
size_t size( unsigned int x )
{
size_t n = 0;
do { ++n; } while ( x /= Base );
return n;
}
int main( void )
{
unsigned int x = 0;
printf( "Enter a non-negative number: " );
scanf( "%u", &x );
size_t n = size( x );
unsigned int digits[n];
for ( size_t i = n; i != 0; x /= Base )
{
digits[--i] = x % Base;
}
for ( size_t i = 0; i < n; i++ )
{
printf( "%u", digits[i] );
}
putchar( '\n' );
}
The program output might look like
Enter a non-negative number: 123456789
123456789
If the compiler does not support variable length arrays then you will need to allocate the array dynamically as for example
unsigned int *digits = malloc( n * sizeof( unsigned int ) );
You don't need to calculate how many digits are in a given integer n at runtime. You can check your compiler's <limits.h> for the maximum number of digits an int can hold.
int n = 124343;
int digits[10]; // INT_MAX is 10-digit long on x86 and x64 (GCC and Clang)
int ndigits;
Another solution is to pre-compute (#chux) the maximum number of digits using macros:
#define INT_DIGIT10_WIDTH ((sizeof(int)*CHAR_BIT - 1)/3 + 1)
int digits[INT_DIGIT10_WIDTH];
The rest is simple:
// Digits are stored in reverse order
for (ndigits = 0; n; n /= 10)
digits[ndigits++] = n % 10;
for (int i = ndigits - 1; i > 0; --i)
printf("%d\t", digits[i]);
If you want to store them in-order:
// Digits are stored in reverse order
for (ndigits = 0; n; n /= 10)
digits[ndigits++] = n % 10;
// Reverse digits by swapping every two parallel elements
for (int i = 0, j = ndigits-1; i < j; ++i, --j) {
int tmp = digits[i];
digits[i] = digits[j];
digits[j] = tmp;
}
for (int i = 0; i < ndigits; ++i)
printf("%d\t", digits[i]);
I was writing my response when the first answer showed up. This will work just fine. The loop in the middle basically isolates each digit by removing all the ones in front of it and then dividing it down to the ones place before adding it to the array.
I have a number that I wish to sort. I know how to sort it in ascending and descending order, but what the question wants is to switch places value in the number.
try this
#include <stdio.h>
unsigned power(unsigned base, unsigned exp){
unsigned result = 1;
while(exp > 0){
if(exp & 1)
result = result * base;
base = base * base;
exp >>=1;
}
return result;//Overflow is not considered
}
int pow10(int exp){
return power(10, exp);
}
int get_num_at(int n, int pos){
int exp = pow10(pos);
return n / exp % 10;//Changed by advice of chux
}
int swap(int n, int pos1, int pos2){
if(pos1 == pos2)
return n;
int n1 = get_num_at(n, pos1);
int n2 = get_num_at(n, pos2);
return n - n1 * pow10(pos1) - n2 * pow10(pos2) + n1 * pow10(pos2) + n2 * pow10(pos1);
}
int length(int n){
int len = 1;
while(n /= 10)
++len;
return len;
}
int arrange(int v){
int len = length(v), half = len / 2;
return (len & 1) ? swap(v, 0, len-1) : swap(v, half-1, half);//0 origin
}
int main (void) {
int v;
scanf("%d", &v);
printf ("%d\n", arrange(v));
}
Continuing from my comment, to answer your question:
How would I modify the code below to get the above or do i have to start a new code?
I would start with a new approach. Why? While you could use a set of place-holders and set various conditions to manipulate the integer values to accomplish a mid-digit or end-digit swap depending on odd/even, it is far easier to simply convert your integer value to a string and then manipulate the characters.
Given you are working with integers, the longest integer you will have to address is INT_MIN (-2147483648), or 11-chars (+1 for the nul-terminating character). You can simply use a static character buffer of 12 chars and call sprintf to convert you integer to a string (while getting its length in the same call). A simple odd/even test and you know to either swap the middle characters or the end characters. To convert the resulting string back to integer, simply use strtol.
You can test for a negative value at the beginning, handle the positive form, and then multiply the resulting value by -1 for return if the value was negative. (note: you should also test for INT_MIN before assigning the positive form as -INT_MIN will not fit in an integer value. You must also check that the resulting integer after you swap digits will fit within an integer as well. -- that is left as an exercise for you).
Putting those pieces together, you can do something similar to:
#include <stdio.h>
#include <stdlib.h>
enum {BASE = 10, MAXS = 12}; /* constants */
int minswap (int v)
{
char buf[MAXS] = "";
int neg = v < 0 ? -1 : 1, /* flag negative numbers */
val = v * neg, /* handle as positive val */
len = sprintf (buf, "%d", val); /* conver to str, get len */
if (len % 2 == 0) { /* val is even */
int m = len / 2;
char tmp = buf[m - 1]; /* swap mid digits */
buf[m - 1] = buf[m];
buf[m] = tmp;
}
else {
char tmp = *buf; /* swap end digits */
*buf = buf[len - 1];
buf[len - 1] = tmp;
}
return (int)strtol (buf, NULL, BASE) * neg;
}
int main (void) {
int v1 = 264802,
v2 = 1357246;
printf (" %d => %d\n", v1, minswap(v1));
printf (" %d => %d\n", v2, minswap(v2));
return 0;
}
Example Use/Output
Using your test values:
$ ./bin/minswap
264802 => 268402
1357246 => 6357241
Look things over and let me know if you have any questions.
Without Library Function Usage
If you have a requirement to no use any of the C-library functions in your minswap function, you can easily replace them with loops with something similar to the following:
enum {BASE = 10, MAXS = 12}; /* constants */
int minswap (int v)
{
char buf[MAXS] = "";
int neg = v < 0 ? -1 : 1, /* flag negative numbers */
val = v * neg, /* handle as positive val */
len = 0;
while (len + 1 < MAXS && val) { /* convert to string get len */
buf[len++] = val % 10 + '0';
val /= 10;
}
/* (you should validate len > 0 here) */
if (len % 2 == 0) { /* val is even */
int m = len / 2;
char tmp = buf[m - 1]; /* swap mid digits */
buf[m - 1] = buf[m];
buf[m] = tmp;
}
else {
char tmp = *buf; /* swap end digits */
*buf = buf[len - 1];
buf[len - 1] = tmp;
}
while (len--) /* convert to int */
val = val * 10 + buf[len] - '0';
return val * neg;
}
(note: there is actually no need to convert to the character values with -/+ '0' since you are simply swapping the values at the mid or end positions, but for sake of completeness, that was included.)
Look things over and let me know if your have further questions.
Here is a solution without any standard library calls, arrays or strings, except for printing the result:
#include <stdio.h>
long long shuffle(int v) {
int i, n, x, d0, d1;
long long p;
/* compute the number of digits and the largest power of 10 <= v */
for (x = v, p = 1, n = 1; x > 9; x /= 10, p *= 10, n++)
continue;
if (n & 1) {
/* odd number of digits, swap first and last */
d0 = v % 10;
d1 = v / p;
return d0 * p + v % p - d0 + d1;
} else {
/* even number of digits, swap middle 2 digits */
for (i = 0, p = 1; i < n / 2 - 1; i++, p *= 10)
continue;
d0 = (v / p) % 10;
d1 = (v / p) / 10 % 10;
return v + p * (d0 - d1) * 9;
}
}
int main(void) {
printf("%d => %lld\n", 0, shuffle(0));
printf("%d => %lld\n", 1, shuffle(1));
printf("%d => %lld\n", 42, shuffle(42));
printf("%d => %lld\n", 24, shuffle(24));
printf("%d => %lld\n", 264802, shuffle(264802));
printf("%d => %lld\n", 1357246, shuffle(1357246));
return 0;
}
Output:
0 => 0
1 => 1
42 => 24
24 => 42
264802 => 268402
Notes:
I do not handle negative numbers
The reversed number might not fit in an int, so I used type long long, but on systems where int would have the same range as long long, you might still get an incorrect result.
Ive completed the assignment and my code is as below. It is a bit primitive, but it works thank you all for your contribution.
int swapvalues(int input, int digit)
{
int swapsort = 0; //initializes swapsort to 0
int lastdigit; //finds he last digit of input
int digits; //the total number of digits - 1
int firstdigit; //finds the first digit of the input
int middledigit; //finds the first middle digit in an even digit number
int secondmiddledigit; //finds the second middle digit in an even digit number
int firsthalf; //the first half of an even digit number
int firsthalf2; //the second half of an even digit number
int spacing; //the spacing between the output and the input
if(digit % 2 != 0)
{
lastdigit = input % 10;
digits = digit - 1;
firstdigit = (int)(input / pow(10, digits));
swapsort = lastdigit;
swapsort *= (int) pow(10, digits);
swapsort += input % ((int)pow(10, digits));
swapsort -= lastdigit;
swapsort += firstdigit;
}
else
{
firsthalf = input / pow(10, (digit / 2));
middledigit = firsthalf % 10;
firsthalf2 = input / pow(10, (digit / 2) - 1);
secondmiddledigit = firsthalf2 % 10;
spacing = (((secondmiddledigit * 10) + (middledigit)) - ((middledigit * 10) + (secondmiddledigit))) * pow(10, ((digit / 2) - 1));
swapsort = input + spacing;
}
return(swapsort);
}
I am new to C so this question may seem a bit stupid :P .
I have an array arr[] which stores numbers from 100 to 999.
Now, I have to take each element of the array and subtract the subsequent digits.
For example if I have a number in that array as 1234 then I need another array that stores 1,2,3,4 distinctly so that I can perform 1-2= -1, 2-3 =-1, 3-4= -1.
So if I change a data like 1234 to char through typecasting then how to store this char into an array and then break it into 1,2,3,4 so that I can call it in a for loop by arr[i].
#include <stdio.h>
#include<string.h>
int main()
{
int t,n,w;
int mod = 1000007;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&w);
int start = 1;
int end = 10;
int i,j,z;
for(i=0;i<=n-2;i++)
{
start = start*10;
end = end*100;
}
end--;
char arr[10000];
for(i= start;i<=end;i++)
{
scanf("%c",&arr[i]);
}
int len = strlen(arr);
int count = 0;
int Value=0;
for(i=0;i<len;i++)
{
char b[10000];
b[0] = arr[i] + '0';
char arr2[10000];
int g = strlen(b);
for(j=0;j<g;j++)
{
strncpy(arr2, b + j, j+1);
}
int k = strlen(arr2);
for(z=0;z<k;z++)
{
int u = arr2[z] - '0';
int V = arr2[z+1] - '0';
if(u>V)
{
Value = Value + (u-V);
}
else
{
Value = Value + (V-u);
}
}
if (Value == w)
{
count++;
}
}
int ans = count % mod;
printf("%d",ans);
}
return 0;
}
Actually its a question from codechef.com called weight of numbers in the easy section of the practice problems
you can split number by digits in this way
int num = 123;
int digits[3];
for (int i = 2; i >= 0; i--)
{
digits[i] = num % 10;
num /= 10;
}
Also if you'll cast num to char that wouldn't help you. You'll just get some character if you try to print it. Nothing more will change.
I am writing a C program which should display me all numbers between 100 and 1000 which sum of digit is 20. I tried this code down here, but it just displays 0 as an ouput when I compile it, can you help me? I also tried moving if(iVsota==20) outside of the while loop. I am using Orwell Dev C++ IDE.
#include <stdio.h>
int main (void)
{
int iVnos=0;
int iOstanek=0;
int iVsota=1;
int iStevec1=100;
for(iStevec1=100; iStevec1<1000; iStevec1++)
{
while(iStevec1>0)
{
iOstanek=iStevec1%100;
iStevec1=iStevec1/10;
iVsota=iOstanek+iVsota;
if(iVsota==20)
{
printf("%i\n", iStevec1);
}
}
}
return(0);
I hope this is better.
Your loop should look like :
for(iStevec1=100; iStevec1<1000; iStevec1++)
{
int c2 = iStevec1/100; // extract third digit
int c1 = (iStevec1%100)/10; // extract second digit
int c0 = (iStevec1%10); // extract first digit
if((c0+c1+c2)==20) // sum and verify
{
printf("%i\n", iStevec1);
}
}
This should work for you:
(Changed the variable names so it's more readable)
#include <stdio.h>
int add_digits(int n) {
static int sum = 0;
if (n == 0)
return 0;
sum = n%10 + add_digits(n/10);
return sum;
}
int main() {
int start, end;
start = 100, end = 1000;
for(start = 100; start <= end; start++) {
if(add_digits(start) == 20)
printf("Number: %d\n", start);
}
return 0;
}
EDIT:
(Your code fixed with comments as explanation)
#include <stdio.h>
int main() {
int iVnos=0;
int iOstanek=0;
int iVsota=0;
int iStevec1=100;
int temp; //temp needed
for(iStevec1=100; iStevec1<=1000; iStevec1++)
{
temp =iStevec1; //assign number to temp
iVsota=0; //set sum every iteration to 0
while(temp>0)
{
iOstanek=temp%10; //You need only % 10 to get the last digit of a number
temp = temp / 10; //'delete' last digit of the number
iVsota+=iOstanek; //add digit to sum
}
if(iVsota==20) //You only need to check the digits after sum is calculated
printf("Number %d\n", iStevec1);
}
return 0;
}
Here's a more generalised method to get the sum of all individual numbers in an integer (assumes positive integers):
int getSumOfDigits(int x)
{
int sum = 0;
while (x > 0)
{
sum += x % 10;
x = x / 10;
}
return sum;
}
int main()
{
for (int i = 100; i <= 1000; i++)
{
if (getSumOfDigits(i) == 20)
{
printf("%d\n", x);
}
}
}
The expression x % 10 is the last digit in the integer. Hence, that's what we add. Then we chop off the last digit in the integer by dividing it by 10. Repeat until we hit zero.
Alternative method, taking advantage of the specifics.
#include <stdio.h>
int main()
{
int c0, c1, c2; /* 3 digits sum to 20 */
for(c0 = 2; c0 < 10; c0++){
c1 = 11 - c0;
c2 = 9;
while(c1 < 10){
printf("%d%d%d\n", c0, c1, c2);
/* or printf("%3d\n", (c0*10+c1)*10+c2); */
c1++;
c2--;
}
}
return(0);
}
Just change 1 thing and you will get what you want
int main (void)
{
int iVnos=0;
int iOstanek=0;
int iVsota=1;
int iStevec1=100;
int temp;
for(iStevec1=100; iStevec1<1000; iStevec1++)
{
temp = iStevec1;
while(temp>0)
{
iOstanek=temp%100;
temp=temp/10;
iVsota=iOstanek+iVsota;
if(iVsota==20)
{
printf("%i\n", iStevec1);
}
}
}
return(0);
}
Enjoy Coding Enjoy Life...
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
/* number of max three digits (max digits = MAX3DIGITS*3) */
#define MAX3DIGITS 100000
/* struct that holds three digits (like 503) */
struct three {
unsigned n : 10;
};
/* a whole number made up of struct threes */
struct num {
struct three n[MAX3DIGITS];
} number[2];
FILE *dg;
int main() {
int naim;
dg=fopen("deneme.txt","w");
for(naim=1;naim<1001;naim++){
int prev = 0;
int x, y, n = 0;
int digits = 2;
number[0].n[0].n = 0;
number[1].n[0].n = 1;
while(!kbhit() && ++n < naim && digits <= MAX3DIGITS) {
//fprintf(stderr, "\r%i", n);
prev = !prev;
for(x = 0; x < digits; x ++) {
y = number[!prev].n[x].n + number[prev].n[x].n;
number[!prev].n[x].n = (y%1000);
number[!prev].n[x+1].n += (y/1000);
}
if(number[!prev].n[digits-1].n) digits ++;
}
fprintf(dg,"\nfib(%i) = %i", n, number[!prev].n[digits-2].n);
for(x = digits-3; x >= 0; x --) {
fprintf(dg,"%03i", number[!prev].n[x].n);
}
fprintf(dg,"\n");
}
printf("sad");
if(kbhit()) getche();
getchar();
getchar();
return 0;
}
This code is writing first 1000 Fibonacci numbers. But my problem is starting 18th number. Until seventeenth number , this code is working. But 18th number is wrong so remaining is wrong. How can I fix it ?
Thank You.
Instead of issuing considerations on the code, I'll just answer the question.
The problem is that you have to initialize (to zero) the memory you're using to store the two numbers. Following a working version of your code, my two small modifications sandwiched between // * comments.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
// *****
#include <mem.h>
// *****
/* number of max three digits (max digits = MAX3DIGITS*3) */
#define MAX3DIGITS 100000
/* struct that holds three digits (like 503) */
struct three {
unsigned n : 10;
};
/* a whole number made up of struct threes */
struct num {
struct three n[MAX3DIGITS];
} number[2];
FILE *dg;
int main() {
int naim;
dg=fopen("deneme.txt","w");
for(naim=1;naim<1001;naim++){
int prev = 0;
int x, y, n = 0;
int digits = 2;
// *****
memset(number, 0, sizeof(number));
// *****
number[0].n[0].n = 0;
number[1].n[0].n = 1;
while(!kbhit() && ++n < naim && digits <= MAX3DIGITS) {
//fprintf(stderr, "\r%i", n);
prev = !prev;
for(x = 0; x < digits; x ++) {
y = number[!prev].n[x].n + number[prev].n[x].n;
number[!prev].n[x].n = (y%1000);
number[!prev].n[x+1].n += (y/1000);
}
if(number[!prev].n[digits-1].n) digits ++;
}
fprintf(dg,"\nfib(%i) = %i", n, number[!prev].n[digits-2].n);
for(x = digits-3; x >= 0; x --) {
fprintf(dg,"%03i", number[!prev].n[x].n);
}
fprintf(dg,"\n");
}
printf("sad");
if(kbhit()) getche();
getchar();
getchar();
return 0;
}