Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何将一个长整数拆分为数千个以便输出?_C - Fatal编程技术网

C 如何将一个长整数拆分为数千个以便输出?

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

例如,如果我的数字为390000,则需要打印为390000。 如果我的数字是1200000,它将被打印为1200 000

起初,我考虑将long-long int赋值给一个字符串,然后为每个可能的字符串长度编写if语句,因为只有11个可能的长度,但这看起来真的很麻烦,也没有必要


有更简单的方法吗?

我想到的一个快速解决方案是:

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
解决方案,我想。你到底为什么要用达夫的设备来做这个,而不是一个简单易读的循环?嗯。。。。POSIX
printf()
中的
有一个很好的观点,但是程序使用的区域设置不是应该由用户(通过适当的环境变量)决定,而不是由程序设置吗?@DevSolar Use
setlocale(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