January 16th, 2013, 06:50 PM

C++, getting the number of digits in an int
In the followig program I need to get the number of digits in an int value that will be different lengths depending on user input.
Code:
#include <iostream>
int main()
{
int NumberOfGroups = 0;
std::cout << "Please enter a date for validation, numbers only without dashes or slashes.";
int NUM = 0;
std::cin >> NUM;
digits = //get number of digits in NUM
if (NUM <= 299 )
{
int NumberOfGroups++;
std::cout << "Num is less than 300" << std::endl;
}
else if ( digits % 3 == .33 )
{
// add two zeros to the left of NUM
}
else if ( digits % 3 == .66 )
{
// add one zero to the left of NUM
}
else
NUM = NUM;
return 0;
}
January 16th, 2013, 09:07 PM

The number of digits is
1 + (int)log10(NUM)
Your program uses integers.
int % int always results in int, unless perhaps there's a 0 divisor. The tests against .33 and .66 aren't helpful, in fact when you learn about floating point representation you'll realize that tests against .33 and .66 will have been used almost never in all the successful programs that have ever been written. Maybe these appear more often than I think in the decimal arithmetic of a common business oriented language.
SPLAT!
c.c: In function ‘main’:
c.c:4:18: warning: division by zero [Wdivbyzero]
/bin/bash: line 1: 5089 Floating point exception(core dumped) $a
[code]
Code tags[/code] are essential for python code and Makefiles!
January 18th, 2013, 01:41 PM

Like this:
Code:
#include <<math.h>
int intDigits( int x )
{
return (int)log10( abs(x) ) + 1 ;
}
Note it does not account for a possible  sign for negative inputs, if you need that add 1 if < 0.
An alternative nonmathematical but generally less efficient approach:
Code:
#include <stdio.h>
int intDigits( int x )
{
char numstr[23] ; // big enough for 64 bit int with sign
return sprintf( numstr, "%d", x ) ;
}
In this second example, the  sign is included for negative values, so if this is not wanted subtract 1 if < 0.
January 18th, 2013, 01:58 PM

Using one of the solutions I suggested, this will do what I think you are trying to do far more succinctly:
Code:
if (NUM < 300 )
{
NumberOfGroups++;
std::cout << "Num is less than 300" << std::endl;
}
else
{
// Pad digits to multiple of three
int digits = intDigits( NUM ) ;
int width = digits + (3  digits % 3) ;
cout << setfill ('0') << setw(width) << NUM ;
}
On another note, it is not very clear how you want the user to enter a value, and your validation is minimal. Date formats are cultural and locale specific; the date 18 January 2013 for example might be expressed:
180113 // usual UK order ddmmyy
011813 // usual US order mmddyy
18012013 // UK ddmmyyyy
01182013 // US ddmmyyyy
20130118 // ISO 8601 order yyyymmdd
Given that a user might respond to your prompt in any of the above ways, and possibly more, it is not at all clear what you expect.
Last edited by clifford; January 18th, 2013 at 02:31 PM.