简体   繁体   中英

Remove thousand separator C-programming

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);
}

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 .

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.

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"));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM