[英]Multiple dynamic float format specifier in C
我幾次想起必須使用float
變量將它們以適當的格式printf
出來,並用一定數量的小數位進行打印。 我知道在C語言中,您可以通過使用以下符號同時指定十進制數字和總數字來輕松設置float
變量的格式:
// Where x and y are natural numbers
printf("%<x>.<y>f", myFloat);
而且我也知道您可以使用*
符號使用兩個變量來動態格式化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
我printf
出來?
我不想創建自己的函數來打印這些數字,我顯然可以做到,但是,如果可能的話,我想在一個較低的水平上解決它。
您可以在運行時創建格式字符串,並根據需要多次使用。
// 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);
您可以編寫一個宏,定義您的默認浮點打印方式:
#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);
宏及其使用方式均使用字符串文字串聯。 格式字符串是在編譯時創建的,因此將觸發有關格式和參數類型不匹配的警告。
當然,格式字符串是否可讀性值得商de。
編輯 :這是如何工作的? 宏M_STR
其參數“字符串化”。 它將其轉換為C字符串文字。 宏定義中可用的運算符#
實現了這一點。
必須使用對輔助宏M_STR_
的間接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);
該解決方案的缺點是字符串和宏的並置在某種程度上很難讀取。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.