2015-05-19 79 views
6

在C++程序中,我想要顯示一列浮點值,以便符號,數字和小數點全部對齊。必要時,多個前導零應填充每個值的整個數字部分。例如:如何在C++中顯示浮點值的多個前導零?

A column of floating point values: 
    +000.0012 
    -000.
    +000.1235 
    -001.2346 
    +012.3457 
    -123.4568 

我有一個精心評論的測試程序,證明了這個問題。但是,正如我在編輯這篇文章,我找到了答案,我需要在這裏:
- Extra leading zeros when printing float using printf?

面臨的關鍵問題是,我使用的"%+04.4f"格式代碼時,我應該使用"%+09.4f",因爲總場寬度我要的是9:

  • 1爲標誌
  • 3爲全數字
  • 1小數點
  • 4爲小數位

我沒有足夠的聲望點評論這篇文章,所以在這裏感謝你,@AndiDog。

我仍然不知道如何使用流格式化標誌獲得多個前導零。但那是另一天的戰鬥。現在我會堅持使用printf和stream的混合。

+0

請參閱:http://stackoverflow.com/questions/1714515/how-can-i-pad-an-int-with-leading-zeros-when-using-cout-operator – NathanOliver

+2

使用std :: setfill(' 0')和std :: setw() – 911

+0

我不認爲'setfilll'將在這種情況下工作。使用'0'作爲填充字符,他的第一個結果最終會像'00 + 0.0012'一樣,而不是所有數字前面的'+'。 –

回答

8

一對夫婦的意見都提到std::setfill('0')std::setw。雖然這些必要的,但它們不足以完成任務。例如,此代碼:

std::cout << std::setfill('0') << std::setw(7) << std::showpos << 0.012; 

將生成:0+0.012作爲其輸出。這顯然不是我們想要的。

我們需要添加std::internal標誌來告訴流插入「內部填充」 - 即,填充應的符號和數字的休息,所以代碼之間插入這樣的:

std::cout << std::setfill('0') << std::setw(7) << std::internal << std::showpos << 0.012; 

...產生我們想要的輸出:+00.012

另請注意,填充字符是「粘滯」的,所以如果您在使用std::setw與數字和非數字類型之間交替使用,則您可能需要/每次都要更改它。否則,諸如std::cout << setw(12) << name;之類的結果將產生如下結果:0000000Jerry,這也是很少需要的。

爲了確保我們總是得到相同的一些地方,小數點後,我們還需要設置std::fixed標誌,並與std::setprecision指定的名額,如:

#include <iostream> 
#include <iomanip> 
#include <vector> 

int main() { 
    std::vector<double> values { 0.1234, 1.234, 1.5555 }; 

    for (auto d : values) 
     std::cout << std::internal << std::showpos << std::setw(9) 
        << std::setprecision(3) << std::setfill('0') << d << "\n"; 
} 

將會產生我相信希望輸出:

+0000.123 
+0001.234 
+0001.556 

有一個情況下,你不會得到,雖然對齊結果是這樣的:如果你有一個數太大,無法在提供的字段,所有之前的地方decim點仍將被打印。例如,如果我們將1e10添加到前面的代碼要打印的數字列表中,則會將其打印爲:+10000000000.000,這顯然不會與其他對齊。

處理這個問題的一個顯而易見的方法就是忍受它,並且如果它經常出現足以關心的問題,請增大字段大小以容納更大的數字。

另一種可能性是使用固定的符號,只有數字低於某個閾值,並切換到(例如)科學記數法以獲取較大的數字。

至少在我的經驗中,這樣的代碼傾向於主要用於財務數據,在這種情況下後者通常是不可接受的。

3

要顯示正號,可以使用std :: showpos。

要顯示前導零,可以使用std :: setw(n)和std :: setfill('0')。

要顯示零後的數字,請使用std :: setprecision(m)。

要顯示+符號和第一個數字之間的零,可以使用std :: internal。

要將數字保持在固定位置,請使用std :: fixed。

#include <iostream>  // std::cout, std::fixed 
#include <iomanip>  // std::setprecision 

int main() { 
    double f =1.234; 
    double g =-12.234; 
    std::cout << std::showpos<< std::internal << std::fixed << std::setprecision(4)<<std::setw(9) <<std::setfill('0') << f << '\n'; 
    std::cout <<std::setw(9)<< std::setfill('0') <<g<<"\n"; //repeat these for a new number 
    return 0; 
    } 


//output: 
//+001.2340 
//-012.2340 
+0

您的代碼打印出'000 + 1.234' – hyde

+0

您應該使用std :: fixed來顯示前導零。打印線將變爲: std :: cout << std :: showpos << std :: fixed << std :: setprecision(4)<< std :: setw(9)<< std :: setfill('0 ')<< f <<'\ n'; –

+1

我的不好,你還需要std :: internal。我現在編輯示例。 –

0

我現在該怎麼做到這一點的唯一方法是顯示符號,然後設置填充,寬度和精度後,你已經顯示的跡象顯示正值。您還需要格式標誌設置爲ios::fixed

#include <iostream> 
#include <iomanip> 
using namespace std; 

int main() 
{ 
    float x[] = { 000.0012, .0123, .1235, 1.2346, 12.3457, 123.4568 }; 
    cout.setf(ios::fixed); 
    for (int i = 0; i < 6; i++) 
     cout << (x[i] > 0 ? '+' : '-') << setfill('0') << setw(8) << setprecision(4) << abs(x[i]) << endl; 
    return 0; 
} 

顯示

+000.0012 
-000.
+000.1235 
-001.2346 
+012.3457 
-123.4568 
+0

這不是「唯一的方法」。查看其他答案 –

+0

@CaioOliveira我從來沒有說過這是唯一的方法。這是我寫這篇文章的唯一途徑。 – NathanOliver