topgun
topgun

Reputation: 2573

Iterating through digits in integer in C

I have an integer like 1191223 and I want to iterate over the digits. I am not sure how to do this in C, is there any easy way to do this?

Thanks.

Upvotes: 16

Views: 62845

Answers (9)

Nick
Nick

Reputation: 26

For my purposes the following short code did the trick.

Having a an integer variable the_integer, and an integer variable sum_of_digits initialized. (line 1) You could do the following:

1) Convert the integer variable to a variable of type string with use of the std::to_string(int) function.

2) Iterate of the characters of the resulting string. for(char& c: str::to_string(the_integer))

3) To convert the characters back to integers use c -'0' . For this solution take a look at the discussion in (Convert char to int in C and C++).

4) .. and adding them the digits together: sum_of_digits += c-'0'

*) you can then print your variables: lines 3 and 4.

int the_integer = 123456789; int sum_of_digits;

for (char& c: std::to_string(the_integer)) {sum_of_digits += c-'0';}

std::cout << "Integer: " << the_integer << std::endl;
std::cout << "Sum of Digits << sum_of_digits << std::endl;

Note that std::to_string() has some notes, please consult the c++ references to see if the code is still relevant for your purposes.

Upvotes: 1

Cyclonecode
Cyclonecode

Reputation: 29991

Something like this:

char data[128];
int digits = 1191223;
sprintf(data, "%d", digits);
int length = strlen(data);
for(int i = 0; i < length; i++) {
   // iterate through each character representing a digit
}

Notice that if you use an octal number like 0100 you also need to change the sprintf(data, "%d", digits); to sprintf(data, "%o", digits);.

Upvotes: 2

moooeeeep
moooeeeep

Reputation: 32502

In the following I assume you mean decimal digits (base 10). Probably you are able to adapt the solutions to other numeral systems by substituting the 10s.

Note, that the modulo operation is a tricky thing concerning negative operands. Therefore I have chosen the data type to be an unsigned integer.

If you want to process the least significant digit first, you could try the following untested approach:

uint32_t n = 1191223;
do {
  uint32_t digit = n%10;
  // do something with digit
}
while (n/=10);

If you prefer to walk through the digits starting from the most significant digit, you could try to adapt the following untested code:

uint32_t n = 1191223;
#define MAX_DIGITS 10 // log10((double)UINT32_MAX)+1
uint32_t div = pow(10, MAX_DIGITS);

// skip the leading zero digits
while ( div && !(n/div) ) div/=10;
if ( !div ) div = 10; // allow n being zero

do {
  uint32_t digit = (n/div)%10;
  // do something with digit
}
while (div/=10);

Upvotes: 5

BRPocock
BRPocock

Reputation: 13914

Forwards, or backwards?

Assuming a positive integer:

  unsigned int n = 1191223;

  while (n != 0) {
       doSomething (n % 10);
       n /= 10;
  }

…will work smallest to largest, or…

EDIT I'd forgotten all about this non-working solution I had here. Note that Very Smart People™ seem to use the smallest-to-largest iteration consistently (both Linux kernel and GLibC's printf, for example, just iterate backwards) but here's a lousy way to do it if you really don't want to use snprintf for some reason…

int left_to_right (unsigned int n) {
  unsigned int digit = 0;

  if (0 == n) {
    doSomething (0);
  } else {
    digit = pow(10, 1.0+ floor(log10(n)));
    while (digit /= 10) {
      doSomething ( (n / digit) % 10 );
    }
  }
}

I assume that it's very silly to assume that you have log10 and pow but not snprintf, so an alternate plan would be

int left_to_right_fixed_max (unsigned int n) {
  unsigned int digit = 1000000000; /* make this very big */
  unsigned int n10 = 10 * n;

  if (0 == n) {
    doSomething (0);
  } else {
    while (digit > n10) { digit /= 10; }
    while (digit /= 10) {
      doSomething ( (n / digit) % 10 );
    }
  }
}

… or, if you really don't have hardware multiply/divide, you can resort to using a table of powers of ten.

int left_to_right (unsigned int n) {
  static const unsigned int digit [] = 
    { 1,
      10,
      100,
      1000,
      10000,
      100000,
      1000000,
      10000000,
      100000000,
      1000000000 /* make this very big */
    };
  static const unsigned char max_place = 10;
  /* length of the above array */

  unsigned char decimal;
  unsigned char place;
  unsigned char significant = 0; /* boolean */

  if (0 == n) {
    doSomething (0);
  } else {
    place = max_place;
    while (place--) {
      decimal = 0;
      while (n >= digit[place]) {
        decimal++;
        n -= digit[place];
      }
      if (decimal | significant) {
        doSomething (decimal);
        significant |= decimal;
      }
    }
  }
}

…which I have adapted from http://www.piclist.com/techref/language/ccpp/convertbase.htm into a somewhat more general-purpose version.

Upvotes: 19

Sangeeth Saravanaraj
Sangeeth Saravanaraj

Reputation: 16597

void access_digits(int n)
{
        int digit;
        if (n < 0) n = -n;
        do {
                digit = n % 10;
                /* Here you can do whatever you
                   want to do with the digit */
        } while ((n/=10) > 0);
}

Upvotes: 2

Dan Fego
Dan Fego

Reputation: 13994

You can use sprintf() to convert it into a char array, and then iterate through that, like so (untested, just to get you started):

int a = 1191223;
char arr[16];
int rc = sprintf(arr, "%d", a);

if (rc < 0) {
    // error
}

for (int i = 0; i < rc; i++) {
    printf("digit %d = %d\n", i, arr[i]);
}

Upvotes: 2

paulsm4
paulsm4

Reputation: 121609

Off the top of my head: "i % 100000", "i % 100000", ...

A recursive solution would let you start from "i%10".

Upvotes: 0

Alexander Oh
Alexander Oh

Reputation: 25621

A hackish way is to convert this to string (see strtol) and then reconvert this to a number. you could use something like character you want - '0'

Upvotes: 0

thiton
thiton

Reputation: 36049

You want to iterate over base-10 digits, but an integer has no concept of arabic notation and digits. Convert it to a string first:

int i = 1191223;
char buffer[16];
char *j;
snprintf(buffer, 16, "%i", i);
for ( j = buffer; *j; ++j ) { /* digit is in *j - '0' */ }

Upvotes: 3

Related Questions