C 如何将一个长整数拆分为数千个以便输出?
例如,如果我的数字为390000,则需要打印为390000。 如果我的数字是1200000,它将被打印为1200 000等 起初,我考虑将long-long int赋值给一个字符串,然后为每个可能的字符串长度编写if语句,因为只有11个可能的长度,但这看起来真的很麻烦,也没有必要C 如何将一个长整数拆分为数千个以便输出?,c,C,例如,如果我的数字为390000,则需要打印为390000。 如果我的数字是1200000,它将被打印为1200 000等 起初,我考虑将long-long int赋值给一个字符串,然后为每个可能的字符串长度编写if语句,因为只有11个可能的长度,但这看起来真的很麻烦,也没有必要 有更简单的方法吗?我想到的一个快速解决方案是: output = [] number = '1209873' aux = reversed(list(number)) counter = 0 for digit in
有更简单的方法吗?我想到的一个快速解决方案是:
output = []
number = '1209873'
aux = reversed(list(number))
counter = 0
for digit in aux:
output.append(digit)
counter += 1
if counter % 3 == 0:
output.append(' ')
spaced_number = reduce(lambda x, y: x + y, reversed(output))
但我相信有更有效的方法来解决你的问题 你可以很容易地做到这一点,首先使用一个足够大的缓冲区来存储完整的
long
数字(和分隔符),然后使用指针算法每隔3个数字插入一个分隔符。例如,如果MAXN
为32
,则可以执行以下操作:
/** separate long long value every 3rd char into 's' */
char *sepnumber (char *s, long long val)
{
char numstr[MAXN] = "";
char *p = s + MAXN - 2;
size_t idx = 0, len = 0;
len = sprintf (numstr, "%lld", val);
while (len--) {
if (idx++ == 3) {
idx = 1;
*p-- = ' ';
}
*p = numstr[len];
if (len) p--;
}
for (idx = 0; *p; p++, idx++) s[idx] = *p; /* copy to s */
s[idx] = *p; /* nul-terminate */
return s;
}
一个简单的例子是:
#include <stdio.h>
#include <stdlib.h>
#define MAXN 32
char *sepnumber (char *s, long long val);
int main (int argc, char **argv) {
long long int lv = argc > 1 ? strtoll (argv[1], NULL, 10) : 1931583282;
char fmtnum[MAXN] = "";
printf (" %lld => %s\n", lv, sepnumber (fmtnum, lv));
return 0;
}
/** separate long long value every 3rd char into 's' */
char *sepnumber (char *s, long long val)
{
char numstr[MAXN] = "";
char *p = s + MAXN - 2;
size_t idx = 0, len = 0;
len = sprintf (numstr, "%lld", val);
while (len--) {
if (idx++ == 3) {
idx = 1;
*p-- = ' ';
}
*p = numstr[len];
if (len) p--;
}
for (idx = 0; *p; p++, idx++) s[idx] = *p; /* copy to s */
s[idx] = *p; /* nul-terminate */
return s;
}
使用达夫设备的另一种方法:
#include <stdio.h>
static char *sep(char *str, long long value)
{
char tmp[32];
char *p = tmp;
char *q = str;
int len;
len = snprintf(tmp, sizeof tmp, "%lld", value);
if (*p == '-') { // Support for negatives
*q++ = *p++;
len--;
}
/*
* Consider 5 mod 3
* len % 3 is evaluated only once. E.g. 5 % 3 = 2
* jumps into the middle of the loop (in this case to "case 2:")
* case 2 and case 1 are evaluated
* loops until NUL is reached evaluating all cases
*/
switch (len % 3) do {
*q++ = ' ';
case 0: *q++ = *p++;
case 2: *q++ = *p++;
case 1: *q++ = *p++;
} while (*p);
*q = '\0';
return str;
}
int main(void)
{
char str[32];
printf("%s\n", sep(str, 1200000));
return 0;
}
如果您在POSIX系统上,并且您的一个地区使用空格作为数字分组符号,请在
printf()
转换说明符中使用撇号(”
)
setlocale(LC_NUMERIC, "SOMETHING");
printf("%'d", 345678); // 345 678
请看这是一个没有任何废话的简单版本。可能还有更有效的方法,但如果是的话,它们不包括字符串处理或浮点数
#include <stdio.h>
#include <inttypes.h>
#include <stdbool.h>
static void print_number (uint32_t n)
{
static bool remove_zeroes = true;
if(remove_zeroes)
{
remove_zeroes = false;
printf("%" PRIu32 " ", n);
}
else
{
printf("%.3" PRIu32 " ", n);
}
}
void print_number_with_spaces (uint32_t n)
{
bool remove_zeroes = true;
while(n > 1000)
{
uint32_t tmp = n;
uint32_t subtract = 1;
while(tmp > 1000)
{
tmp /= 1000;
subtract *= 1000;
}
print_number(tmp);
if(subtract >= 1000)
{
n -= tmp*subtract;
}
}
print_number(n);
}
int main(int argc, char* argv[])
{
print_number_with_spaces(1200000);
}
#包括
#包括
#包括
静态无效打印编号(uint32)
{
静态bool remove_zeroes=true;
如果(删除0)
{
删除零=假;
printf(“%PRIu32”,n);
}
其他的
{
printf(“%.3”PRIu32“,n);
}
}
带空格的无效打印号(uint32)
{
bool remove_zeroes=true;
而(n>1000)
{
uint32_t tmp=n;
uint32\u t减法=1;
而(tmp>1000)
{
tmp/=1000;
减去*=1000;
}
打印号码(tmp);
如果(减去>=1000)
{
n-=tmp*减法;
}
}
打印号码(n);
}
int main(int argc,char*argv[])
{
打印带有空格的数字(1200000);
}
一种使用空格分隔数千个位置的简单打印方法使用递归。也适用于负值
void print_1000(long long x) {
long long msgroups = x / 1000;
int lsgroup = x % 1000;
if (msgroups) {
print_1000(msgroups);
char separator = ' '; // adjust as deisred
printf("%c%03d", separator, abs(lsgroup));
} else {
printf("%d", lsgroup);
}
}
样本使用
int main(void) {
print_1000(0); puts("");
print_1000(-1); puts("");
print_1000(LLONG_MAX); puts("");
print_1000(LLONG_MIN); puts("");
return 0;
}
输出
1 200 000
0
-1
9 223 372 036 854 775 807
-9 223 372 036 854 775 808
如果您使用
a%1000
,您会得到什么?继续存储number%1000
。然后将其反转并显示。顺便说一句,您的12000000表示是错误的。长整型
必须至少是64位,根据规范,这是19位,可能是负号,如果是无符号长整型
,则为20位。将数字写入字符串是个好主意,但随后使用循环输出数字和空格。你所要做的就是找出第一个缺口应该在哪里。在这之后,间隔是每三位数。如果不向下滚动,任何不包括呼叫的应答都是不完整的。不同的地区,不同的分隔符代表数千个字符。还请注意,这看起来很像Python
(尽管可以使用C
定义大量宏)。但是OP要求的是C
解决方案,我想。你到底为什么要用达夫的设备来做这个,而不是一个简单易读的循环?嗯。。。。POSIXprintf()
中的“
有一个很好的观点,但是程序使用的区域设置不是应该由用户(通过适当的环境变量)决定,而不是由程序设置吗?@DevSolar Usesetlocale(LC\u NUMERIC,NULL)
(或者setlocale(LC\u ALL,NULL)
)到或者setlocale(LC\u NUMERIC,”)
0
-1
9 223 372 036 854 775 807
-9 223 372 036 854 775 808