Reputation: 579
Im trying to make a simple function which can convert a number with a thousand separator to an integer without the separator. All my numbers are within the range of 0 to 999.999, so my initial though was to just handle it like a double and then multiply it by 1000 and call it a day, but is there a more generel way of doing this?:
#include <stdio.h>
main() {
double a;
a=369.122;
int b;
b = a * 1000;
printf("b is %d", b);
}
Where is my current solution:
#include <stdio.h>
main() {
char *XD = "113.321";
int s1, s2;
sscanf(XD, "%i.%i", &s1, &s2);
printf("%i", s1 * 1000 + s2);
}
Upvotes: 1
Views: 421
Reputation: 213266
A rugged, generic solution is to use a string, then simply skip everything that is not a digit. That way you don't have to worry about locale etc. (Several countries use ,
for decimals and .
for thousand separator, while English-speaking counties do the opposite. And spaces are also sometimes used for thousand separator.)
#include <stdint.h>
#include <inttypes.h>
#include <ctype.h>
#include <stdio.h>
uint32_t digits_only (const char* str_number)
{
uint32_t result = 0;
for(size_t i=0; str_number[i] != '\0'; i++)
{
if(isdigit(str_number[i]))
{
result *= 10;
result += (uint32_t)str_number[i] - '0';
}
}
return result;
}
int main (void)
{
printf("%" PRIu32 "\n", digits_only("123,456"));
printf("%" PRIu32 "\n", digits_only("123.456"));
printf("%" PRIu32 "\n", digits_only("blabla 123 blabla 456 blabla"));
}
Upvotes: 0
Reputation: 60056
You can simply parse the input yourself and ignore the separators. Parsing integers is easy:
#include <stdio.h>
int main()
{
int c;
unsigned n = 0, acc = 0;
while(EOF!=(c=getchar())){
if(c>='0' && c<='9')
acc = 10*n + c-'0';
else if(c == '.') //ignore your separator
continue;
else
break; //not a digit and not a separator -- end parsing
if(acc < n)
fprintf(stderr, "overflow\n");
n = acc;
}
printf("got %d\n", n);
}
If you want very hi-perf., avoid the getchar
and parse a buffered string (or at least use getchar_unlocked
).
Alternatively, you can lex the string, copy legal characters to a buffer, and then run strtoul or similar on that buffer.
You should only only need like 22 characters for the buffer max (assuming base 10) or else 64 bit integers would start overflowing if you parsed them from a buffer that needed more digits.
Upvotes: 0
Reputation: 234635
Using a double
for this is not appropriate due to floating point imprecision: you might find that when multiplied by 1000 and truncate to an int
, you end up with a number that is 1 less than you really want.
Also note that the largest value for an int
can be as small as 32767. On such a platform, you would overflow b
.
If I were you, I'd use a long
throughout and introduce the 1000s separator when you want to display the value. For a positive number x
, the first 1000 is attained using x / 1000
, the final 1000 using x % 1000
.
Upvotes: 4