Home > Enterprise >  Breaking down a number into digits - C
Breaking down a number into digits - C

Time:12-19

I'm trying to create a program that breaks down a number into its component digits.

The code I've written so far is as follows:

#include <stdio.h>

int main() {

int num;
int digits;
int count = 1;

printf("Insert a positive number: ");

do {

    scanf("%d", &num);

} while (num <= 0);

printf("In digits... \n");

// Number in digits
while (num != 0) {
    digits = num % 10;
    printf("Digit %d --> %d \n", count, digits);
    num /= 10;
    count  ;
}

}

The digits of the number are printed correctly, but in reverse order!

Insert a positive number: 345
In digits...
Digit 1 --> 5
Digit 2 --> 4 
Digit 3 --> 3 

I can't figure out how to fix this, can anyone help me?

CodePudding user response:

Your code prints them in reverse because you are starting with the right-most digit (by taking the modulo by 10) each time, then dividing by 10.

To print from left to right, you could have:

#include <stdint.h>

void print_uint32_digits(uint32_t val)
{
    int started = 0; // Flag to say we have started printing digits

    // Special case for when val is zero
    if (val == 0u)
    {
        printf("0\n");
        return;
    }

    for (uint32_t divider = 1000000000u; divider != 0u; divider /= 10u)
    {
        uint32_t num = val / divider;

        if (num > 0u || started)
        {
            printf("%c", num   '0');
            started = 1;
            val -= (num * divider);
        }
    }
    printf("\n");
}

Some notes - I've used uint32_t because it is unsigned and a nice length. To make it work with plain "ints" would involve handling the case of negative numbers, which is more complex. I don't know if you need to handle negative numbers. (Also, ints on your platform could be 64-bit, so the initial divider would have to be adjusted accordingly.)

The 'started' flag is used to signal when we have output at least one digit, to ensure zeros get printed correctly. Until that flag is set, leading zeros are not printed.

CodePudding user response:

You're printing the number mod 10, which is the last digit, then dividing the number by 10 and repeating until the number is zero. So it prints the digits from right to left.
If you want to print from left to right, you need to print the digit that has the highest power of ten first. Here's a naive way to do that, by first finding the highest power of ten the number has a digit for and then using a for loop to go from that power to one to print the digits from left to right:

void print_digits(int n) {
  int mask = 1;
  for(int n2 = n; n2; n2 /= 10) mask *= 10; // find the left-most power of ten
  for(int i = 1; mask > 1; mask /= 10) // loop over the mask to 1
    printf("Digit %d --> %d\n", i  , (n % mask) * 10 / mask);
    // print the digit number and increment the digit counter
    // extract and print the digit: 
    //    `n % mask` gets rid of everything to the left
    //    `* 10 / mask` gets rid of everything to the right
}

You could also make a simpler solution using the standard library function sprintf (string print formatted) to put the int into a string and then print from that, like so:

void print_digits(int n) {
  char num[11]; // 32-bit int up to 9 digits, possible '-', and \0 -> 11
  sprintf(num, "%d", n);
  for (int i = 0; num[i]; i  )
    printf("Digit %d --> %c\n", i   1, num[i]);
}

The second might also be a tiny bit more performant due to not involving division, but I'm not certain of that and such minor differences don't matter for a problem like this anyway

  • Related