0

I'm reading an integer from a file using fscanf(fp, "%d", &n) function.

Is there a way to know how many digits that number has without loops?

Mattia Righetti
  • 1,265
  • 1
  • 18
  • 31
  • 1
    There is no reason why you would want to do that without loops. All present answers are inferior to the simple `unsigned int digits = 1; while(n > base) { n /= base; digits++; }`. Using strings, float numbers and other such nonsense is just bad programming. You've started a competition over who can write the worst program, so I think this question is harmful to future readers. – Lundin Feb 18 '16 at 12:15
  • `unsigned int digits = 1; not_a_loop: if(n > base) { n /= base; digits++; goto not_a_loop; }` There you go. 100 times more effective than any of the answers posted. – Lundin Feb 18 '16 at 12:20
  • @Lundin, certainly you meant `while(n >= base)`. (>= vs >). As for me I would have used: `unsigned int digits = 0; do { digits++; n /= base; } while(n); }`. – chux - Reinstate Monica Feb 18 '16 at 16:30
  • similar to http://stackoverflow.com/q/1068849/2410359 (possible dupe) – chux - Reinstate Monica Feb 18 '16 at 18:21
  • @Lundin - you may like [`int n = 1; while (n /= 10) n++;`](http://stackoverflow.com/a/1069045/2410359) – chux - Reinstate Monica Feb 18 '16 at 18:25

10 Answers10

4

You can try:

int count = 0;
fscanf(fp, "%d%n", &n, &count);

The %n specifier puts in count the number of characters read so far.

However, this number can be larger that the number of digits of n because the %d specifier allows skipping whitespace characters before it reads the number.

Check @pmg's answer to see how to count those whitespaces.

Community
  • 1
  • 1
axiac
  • 68,258
  • 9
  • 99
  • 134
  • See my answer. We had the same idea, but I counted the whitespace and subtracted from the result. – pmg Feb 18 '16 at 11:53
3
int optionalwhitespace, characters;
if (fscanf(fp, " %n%d%n", &optionalwhitespace, &n, &characters) != 1) /* error */;
characters -= optionalwhitespace;
// characters now has the number of characters read to interpret the value in n
pmg
  • 106,608
  • 13
  • 126
  • 198
2

yes, by reading it as a string:

char buffer[256];
fscanf(fp, "%s", buffer);
int length = strlen(buffer);

NOTE: if it is a negative number, you might want to discount the - sign...

Suppose you still want to have the integer value:

int n = atoi(buffer);
Chris Maes
  • 35,025
  • 12
  • 111
  • 136
1

By using the log function:

int number_of_digits(unsigned int i)
{
    return (int)(log(i+1) / log(10)) + 1;
}

int main (void)
{
    int i = 52;
    printf("%d has %d digits\n", number_of_digits(i));
}
Mathieu
  • 8,840
  • 7
  • 32
  • 45
1

For code golf approach, just return the value of snprintf()

width = snprintf(0, 0, "%u", (unsigned) n);
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

You can use snprinf, which is a better option than itoa:

int x = 0;
scanf( "%d", &x );
char buffer[20] = "";
snprintf(buffer, sizeof(buffer), "%d", x);
printf( "num of digits = %d", strlen(buffer) );
artm
  • 17,291
  • 6
  • 38
  • 54
  • Why 20? Could use 1 or `printf( "num of digits = %d", snprintf(0, 0, "%d", x) );` – chux - Reinstate Monica Feb 18 '16 at 17:47
  • @chux - the syntax looks very strange to me, but indeed it works. `snprintf` manpage never mentions the first param can be NULL - so I suppose that exploit must come from inspecting the code of `snprintf` itself?? – artm Feb 19 '16 at 11:32
  • Rather than derived references like a manapge, consider using the C spec. Draft versions readily google-able on-line. "`snprintf(char * restrict s, size_t n, const char * restrict format, ...);` ... If n is zero, nothing is written, and s may be a null pointer. ... The snprintf function returns the number of characters that would have been written had n been sufficiently large ..." No need for exploit or inspecting the code. – chux - Reinstate Monica Feb 19 '16 at 15:45
0

try this:

#include <math.h>
number > 0 ? (int) log10 ((double) number) + 1 : 1;
Marinos K
  • 1,779
  • 16
  • 39
0

You can just count log10 of that number and round it up like so:

int length = ceil(log10((double)n)) + 0.5;

+ 0.5 Is for casting floating point number to integer, because number like 3 cant be written explicitly in floating point representation doing (int)3.0 may yield 2. I am assuming that ceil doesn't return answer off by 0.5 which is never going to happen.

8bra1nz
  • 717
  • 7
  • 19
0

Is there a way to know how many digits that number has without loops?

A recursion solution

unsigned digit_count(unsigned x) {
  if (x >= 10) return digit_count(x /10) + 1;
  return 1;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
-1
#include<math.h>

//rest of program
fscanf(fp, "%d", &n)
int length = (int)(log10(n)) +1;
//rest of program
e.upton
  • 62
  • 4