我试图创建一个简单的函数,它可以将一个千位分隔符的数字转换为一个没有分隔符的整数。我的所有数字都在0到999.999的范围内,所以我的初始版本只是处理它就像一个double然后将它乘以1000并称之为一天,但有更多的方法这样做吗?:
#include <stdio.h>
main() {
double a;
a=369.122;
int b;
b = a * 1000;
printf("b is %d", b);
}
我目前的解决方案在哪里:
#include <stdio.h>
main() {
char *XD = "113.321";
int s1, s2;
sscanf(XD, "%i.%i", &s1, &s2);
printf("%i", s1 * 1000 + s2);
}
答案 0 :(得分:4)
由于浮点不精确,使用double
是不合适的:您可能会发现当乘以1000并截断为int
时,最终会得到一个小于1的数字你真的想要。
另请注意,int
的最大值可以小到32767.在这样的平台上,您会溢出b
。
如果我是你,我会在整个过程中使用long
并在您想要显示值时引入1000s分隔符。对于正数x
,前1000个使用x / 1000
,最后1000个使用x % 1000
。
答案 1 :(得分:0)
您可以自己简单地解析输入并忽略分隔符。 解析整数很容易:
#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);
}
如果你想要非常高性能,请避开getchar
并解析缓冲的字符串(或者至少使用getchar_unlocked
)。
或者,您可以使用字符串,将合法字符复制到缓冲区,然后在该缓冲区上运行strtoul或类似字符。
对于缓冲区最大值(假设基数为10),您应该只需要22个字符,否则如果从需要更多数字的缓冲区中解析它们,则64位整数将开始溢出。
答案 2 :(得分:0)
坚固耐用的通用解决方案是使用字符串,然后简单地跳过不是数字的所有内容。这样你就不必担心语言环境等了。(有几个国家使用,
表示小数,.
表示千位分隔符,而说英语的国家却反其道而行之。用于千位分隔符。)
#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"));
}