【问题标题】:Printing a float with commas in C [duplicate]在C中用逗号打印一个浮点数[重复]
【发布时间】:2013-01-30 04:38:11
【问题描述】:

可能重复:
Output 1000000 as 1,000,000 and so on

我有一个格式为 xxxxxxxx.xx 的浮点变量(例如 11526.99)。我想用逗号将其打印为 11,562.99。如何在 C 中插入逗号?

【问题讨论】:

  • @mvp:这是一个 C++ 问题,这个问题被标记为 C。
  • AFAIK,POSIX 或 C 标准中没有标准方法可以在不使用语言环境的情况下格式化数字,但您说这就是您想要的。您可以找到strfmon_l(),但这需要一个语言环境并且用于格式化货币。如果您设置语言环境,您可以影响fprintf() 等。但我不知道不受语言环境影响的通用数字格式化程序(这并不是说没有)。
  • 如果您想找到 Plauger 的 "The Standard C Library" 的副本,它包含一个根据区域设置将数字格式化为货币或数字的功能。它适用于 C89 版本的语言环境,比 C99 或 C11 版本稍微简单一些。 (AFAIK,C99 和 C11 setlocale()localeconv() 函数是相同的。)
  • 您可能会在What are the formal and practical constraints on the values in struct lconv describing a locale 中找到一些有用的信息。我有一些代码可以实现那里描述的内容——如果需要,请与我联系(请参阅我的个人资料)。它部分源自 Plauger 的工作,但在其他更改中也适用于 C99。
  • 谁将此标记为重复没有看到这是一个 C 问题,而重复是一个 C++ 问题

标签: c floating-point floating-point-conversion


【解决方案1】:

试试:

#include <locale.h>
#include <stdio.h>

int main()
{
    float f = 12345.67;

    // obtain the existing locale name for numbers    
    char *oldLocale = setlocale(LC_NUMERIC, NULL);

    // inherit locale from environment
    setlocale(LC_NUMERIC, "");

    // print number
    printf("%'.2f\n", f);

    // set the locale back
    setlocale(LC_NUMERIC, oldLocale);
}

这取决于当前的语言环境。 C 和 POSIX 语言环境没有千位分隔符。您可以自己将其设置为您知道使用千位分隔符的语言环境,而不是从环境中继承语言环境。在我的系统上,使用 "en_NZ" 提供了千位分隔符。

【讨论】:

  • 我试过了。但是我正在执行它的服务器没有设置语言环境,最重要的是我不打算为此使用语言环境。
  • @Jw123:您想在不使用语言环境的情况下以特定于语言环境的方式格式化数字?
  • @Jw123:如果我可以问,为什么你不能使用语言环境,即使是暂时的(如果你的服务器上没有设置LC_NUMERIC,我已经修改了我的代码来展示如何做到这一点那么您可以手动输入区域名称,例如 "en_US" 或使用数千个分隔符的其他名称)?
【解决方案2】:

下面的 addcommas 函数是一个版本 locale-less,它允许负浮点数(但不适用于像 3.14E10 这样的指数)

#include <stdio.h>
#include <string.h>

#define DOT     '.'
#define COMMA   ','
#define MAX     50

static char commas[MAX]; // Where the result is

char *addcommas(float f) {
  char tmp[MAX];            // temp area
  sprintf(tmp, "%f", f);    // refine %f if you need
  char *dot = strchr(tmp, DOT); // do we have a DOT?
  char *src,*dst; // source, dest

  if (dot) {            // Yes
    dst = commas+MAX-strlen(dot)-1; // set dest to allow the fractional part to fit
    strcpy(dst, dot);               // copy that part
    *dot = 0;       // 'cut' that frac part in tmp
    src = --dot;    // point to last non frac char in tmp
    dst--;          // point to previous 'free' char in dest
  }
  else {                // No
    src = tmp+strlen(tmp)-1;    // src is last char of our float string
    dst = commas+MAX-1;         // dst is last char of commas
  }

  int len = strlen(tmp);        // len is the mantissa size
  int cnt = 0;                  // char counter

  do {
    if ( *src<='9' && *src>='0' ) {  // add comma is we added 3 digits already
      if (cnt && !(cnt % 3)) *dst-- = COMMA;
      cnt++; // mantissa digit count increment
    }
    *dst-- = *src--;
  } while (--len);

  return dst+1; // return pointer to result
}

如何调用它,例如(main例子)

int main () {

   printf ("%s\n", addcommas(0.31415));
   printf ("%s\n", addcommas(3.1415));
   printf ("%s\n", addcommas(31.415));
   printf ("%s\n", addcommas(314.15));
   printf ("%s\n", addcommas(3141.5));
   printf ("%s\n", addcommas(31415));
   printf ("%s\n", addcommas(-0.31415));
   printf ("%s\n", addcommas(-3.1415));
   printf ("%s\n", addcommas(-31.415));
   printf ("%s\n", addcommas(-314.15));
   printf ("%s\n", addcommas(-3141.5));
   printf ("%s\n", addcommas(-31415));
   printf ("%s\n", addcommas(0));

  return 0;
}

编译指令示例

gcc -Wall comma.c -o comma

在做

./comma

应该输出

0.314150
3.141500
31.415001
314.149994
3,141.500000
31,415.000000
-0.314150
-3.141500
-31.415001
-314.149994
-3,141.500000
-31,415.000000
0.000000
  • DOT 设置为点
  • COMMA 设置为应为逗号的内容
  • MAX 设置为 50 假定转换为字符串的浮点数不会超过 49 个字符(增加 MAX 有疑问)
  • 从作为参数给出的 float 返回指向 commas 添加的字符串的指针,指向静态区域的指针,因此
    • addcommas 不是reentrant,并且返回的指针所指向的值(通常)在每次调用后都会改变,例如。
    • in char *a = addcommas(3.1415) ; char *b = addcommas(2.7182) ; a 在第二次调用 addcommas 后无法再安全使用

【讨论】:

  • 谢谢你,ring0。那很有帮助。我尝试实现它,但在以下行“char *addcommas(float f) {” 中出现以下错误“'addcommas' 的类型冲突”
  • @Jw123 听起来您已经设法添加了自己造成的语法错误。
  • 我猜没有语法错误。我不确定出了什么问题。除此之外,当调用 addcommas 函数时,从“int”类型分配给“char [MAX]”类型时,我又遇到了一种错误 - 不兼容的类型。我正在调用这样的函数 char cost_comma[MAX];成本逗号=添加逗号(成本);成本是浮动变量。
猜你喜欢
  • 2021-06-22
  • 2021-01-11
  • 1970-01-01
  • 2015-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多