首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在C中格式化一个从1123456789到1,123,456,789的数字?

如何在C中格式化一个从1123456789到1,123,456,789的数字?
EN

Stack Overflow用户
提问于 2009-09-20 07:38:19
回答 18查看 105.6K关注 0票数 96

如何在C语言中将一个数字从1123456789格式转换为1,123,456,789格式?我试着使用printf("%'10d\n", 1123456789);,但不起作用。

你能给我一些建议吗?解决方案越简单越好。

EN

回答 18

Stack Overflow用户

发布于 2012-07-28 04:31:10

如果您的printf支持'标志(如POSIX2008printf()所要求的那样),那么只需适当地设置您的语言环境即可。示例:

代码语言:javascript
运行
复制
#include <stdio.h>
#include <locale.h>

int main(void)
{
    setlocale(LC_NUMERIC, "");
    printf("%'d\n", 1123456789);
    return 0;
}

并构建和运行:

代码语言:javascript
运行
复制
$ ./example 
1,123,456,789

在Mac OS X和Linux (Ubuntu 10.10)上测试。

票数 90
EN

Stack Overflow用户

发布于 2011-09-17 21:57:16

太棒了!我一直都在这么做,在linux上使用了gcc/g++和glibc,是的,‘运算符可能是非标准的,但我喜欢它的简单性。

代码语言:javascript
运行
复制
#include <stdio.h>
#include <locale.h>

int main()
{
    int bignum=12345678;

    setlocale(LC_ALL,"");

    printf("Big number: %'d\n",bignum);

    return 0;
}

给出以下输出:

大数字: 12,345,678

只需记住其中的“setlocale”调用,否则它不会格式化任何内容。

票数 7
EN

Stack Overflow用户

发布于 2011-03-18 07:10:01

也许一个地区感知的版本会很有趣。

代码语言:javascript
运行
复制
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#include <limits.h>

static int next_group(char const **grouping) {
    if ((*grouping)[1] == CHAR_MAX)
        return 0;
    if ((*grouping)[1] != '\0')
        ++*grouping;
    return **grouping;
}

size_t commafmt(char   *buf,            /* Buffer for formatted string  */
                int     bufsize,        /* Size of buffer               */
                long    N)              /* Number to convert            */
{
    int i;
    int len = 1;
    int posn = 1;
    int sign = 1;
    char *ptr = buf + bufsize - 1;

    struct lconv *fmt_info = localeconv();
    char const *tsep = fmt_info->thousands_sep;
    char const *group = fmt_info->grouping;
    char const *neg = fmt_info->negative_sign;
    size_t sep_len = strlen(tsep);
    size_t group_len = strlen(group);
    size_t neg_len = strlen(neg);
    int places = (int)*group;

    if (bufsize < 2)
    {
ABORT:
        *buf = '\0';
        return 0;
    }

    *ptr-- = '\0';
    --bufsize;
    if (N < 0L)
    {
        sign = -1;
        N = -N;
    }

    for ( ; len <= bufsize; ++len, ++posn)
    {
        *ptr-- = (char)((N % 10L) + '0');
        if (0L == (N /= 10L))
            break;
        if (places && (0 == (posn % places)))
        {
            places = next_group(&group);
            for (int i=sep_len; i>0; i--) {
                *ptr-- = tsep[i-1];
                if (++len >= bufsize)
                    goto ABORT;
            }
        }
        if (len >= bufsize)
            goto ABORT;
    }

    if (sign < 0)
    {
        if (len >= bufsize)
            goto ABORT;
        for (int i=neg_len; i>0; i--) {
            *ptr-- = neg[i-1];
            if (++len >= bufsize)
                goto ABORT;
        }
    }

    memmove(buf, ++ptr, len + 1);
    return (size_t)len;
}

#ifdef TEST
#include <stdio.h>

#define elements(x) (sizeof(x)/sizeof(x[0]))

void show(long i) {
    char buffer[32];

    commafmt(buffer, sizeof(buffer), i);
    printf("%s\n", buffer);
    commafmt(buffer, sizeof(buffer), -i);
    printf("%s\n", buffer);
}


int main() {

    long inputs[] = {1, 12, 123, 1234, 12345, 123456, 1234567, 12345678 };

    for (int i=0; i<elements(inputs); i++) {
        setlocale(LC_ALL, "");
        show(inputs[i]);
    }
    return 0;
}

#endif

这确实有一个bug (但我认为这是一个相当小的bug)。在二的补码硬件上,它不会正确地转换最负的数,因为它试图用二的补码中的N = -N;将负数转换为等价的正数,最大负数没有对应的正数,除非你将它提升为更大的类型。解决这个问题的一种方法是将number提升为相应的无符号类型(但这在某种程度上不是微不足道的)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1449805

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档