簡體   English   中英

C語言中的多個動態浮點格式說明符

[英]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 ,我不得不重復執行這兩個xy變量數千次。 我一直喜歡#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;
}

現在你可以看到, 這是一個有點多余了,我在想: 是不是有什么特別的系統不變或格式技術,我可以使用,以避免一遍又一遍地重復着同樣的價值觀對每個floatprintf出來?

我不想創建自己的函數來打印這些數字,我顯然可以做到,但是,如果可能的話,我想在一個較低的水平上解決它。

您可以在運行時創建格式字符串,並根據需要多次使用。

// 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM