C中的多个动态浮点格式说明符

时间:2015-11-03 17:50:50

标签: c floating-point precision

我多次使用float个变量来处理printf个变量,并使用一定数量的小数位进行格式化。我知道在C中,您可以使用以下表示法轻松格式化float变量,以指定小数位和总位数:

// Where x and y are natural numbers
printf("%<x>.<y>f", myFloat);

而且我也知道您可以使用*符号来dynamically format a float使用两个变量,如下所示:

// Where x and y are natural numbers
printf("%*.*f", x, y, myFloat);

我最近遇到了一个非常多余的情况:当我必须printf使用相同的动态格式float多个x时,我必须重复这两个y#define变量数千次。我总是喜欢#define FLOAT_FORMAT_SIZE 10 #define FLOAT_FORMAT_PRECISION 3 int main(int argc, char *argv[]) { // Anything I have to do... // Output printf("%*.*f, %*.*f, %*.*f, %*.*f", FLOAT_FORMAT_SIZE, FLOAT_FORMAT_PRECISION, myFloat1, FLOAT_FORMAT_SIZE, FLOAT_FORMAT_PRECISION, myFloat2, FLOAT_FORMAT_SIZE, FLOAT_FORMAT_PRECISION, myFloat3, FLOAT_FORMAT_SIZE, FLOAT_FORMAT_PRECISION, myFloat4 ); return 0; } 我的常量,以便将来可以轻松更改它们,所以我的程序看起来像:

float

现在你可以看到这有点太多了,我想知道:是不是有任何特殊的系统常量或格式技术我可以用来避免重复相同的值每个printfanswer=input("do you have an existing cell phone plan? Reply yes or no in lowercase") if answer==choice2: response=input("are you considering a CONTRACTUAL or HYBRID cell phone? Write the options in capitals") if response not in cell: print("consider a prepaid cell phone") if answer==choice1: cool=input("do you have a free upgrade?") if cool==choice2: print(response) if response not in cell: print ("consider a prepaid cell phone") if cool==choice1: print ("upgrade your new phone") 出来的一遍又一遍

我不想创建自己的函数来打印这些数字,我显然可以这样做,但如果可能的话,我想在更低的层次上解决它。

2 个答案:

答案 0 :(得分:2)

您可以在运行时创建格式字符串,并根据需要多次使用它。

// Create the format string.
char formatString[100]; // Make it large enough.
sprintf(formatString, "%%%d.%df", FLOAT_FORMAT_SIZE, FLOAT_FORMAT_PRECISION);

// Use the format string to print a float
printf(formatString, myFloat1);
printf(formatString, myFloat2);
printf(formatString, myFloat3);
printf(formatString, myFloat4);

答案 1 :(得分:2)

您可以编写一个宏来定义打印浮动的默认方式:

#define FLOAT_FORMAT_SIZE 10
#define FLOAT_FORMAT_PRECISION 3

#define M_STR(x) M_STR_(x)
#define M_STR_(x) #x

#define FLOAT_FMT                       \
    "%" M_STR(FLOAT_FORMAT_SIZE)        \
    "." M_STR(FLOAT_FORMAT_PRECISION)   \
    "f"

然后您的printf语句将如下所示:

printf(FLOAT_FMT ", " FLOAT_FMT ", " FLOAT_FMT ", " FLOAT_FMT,
    myFloat1, myFloat2, myFloat3, myFloat4);

宏及其使用方式都使用字符串文字串联。格式字符串是在编译时创建的,因此将触发有关格式和参数类型不匹配的警告。

当然,格式字符串是否具有可读性是值得商榷的。

修改:这是如何运作的?宏M_STR“字符串化”其参数;它将它变成C字符串文字。宏定义中可用的运算符#实现了这一点。

必须使用辅助宏M_STR_的间接,以便首先扩展宏参数。如果没有此辅助宏,M_STR(FLOAT_FORMAT_SIZE)将扩展为"FLOAT_FORMAT_SIZE"。通过M_STR_绕行,宏FLOAT_FORMAT_SIZE会在变为字符串之前展开,结果字符串为"10"

因此,宏FLOAT_FMT扩展为

"%"   "10"   "."   "3"   "f"

C编译器连接相邻的字符串文字,因此宏的最终结果等同于"%10.3f"

构造格式字符串时也是如此:

printf(FLOAT_FMT ", " FLOAT_FMT ", " FLOAT_FMT ", " FLOAT_FMT,
    myFloat1, myFloat2, myFloat3, myFloat4);

实际上是:

printf("%10.3f, %10.3f, %10.3f, %10.3f",
    myFloat1, myFloat2, myFloat3, myFloat4);

这个解决方案的一个缺点是字符串和宏的并置有点难以阅读。