2017-10-13 46 views
25

我正在使用std :: ostringstream將雙精度格式化爲具有特定格式的字符串(使用撇號作爲數千個分隔符)。但是,在某些情況下,ostringstream給了我不同於我預期的結果。std :: ostringstream放置錯誤的位置?

據我所知,以下代碼的預期輸出應爲「+01」;而是輸出「0 + 1」。我在這裏做錯了什麼,我如何得到我需要的結果?

#include <iomanip> 
#include <iostream> 
#include <sstream> 

int main() 
{ 
    std::ostringstream stream; 
    stream << std::showpos; // Always show sign 
    stream << std::setw(3); // Minimum 3 characters 
    stream << std::setfill('0'); // Zero-padded 
    stream << 1; // Expected output: "+01" 

    std::cout << stream.str(); // Output: "0+1" 
    return 0; 
} 

Code on ideone

回答

36

有用於填充,left, right, and internal三個選項。

你想要internal填充符號和值之間。

stream << std::setfill('0') << std::internal; // Zero-padded 
0

也就是說,不幸的是,它是如何工作的。 '0'用作填充字符,不作爲數字的一部分。

要解決它,你必須輸出的+或者 - 另:

std::ostringstream oss; 
oss << "+-"[x<0]; 
oss << std::setw(2) << std::setfill('0') << std::abs(x); 
return/cout/whatever oss.str(); 
+0

只有幾個字符,'oss << (x> = 0? :'+':' - ');在我看來,'會更具可讀性。 – YSC

+1

有可能獲得PO想要的。看@Pete Becker的答案或我的。 – informaticienzero

11

您可以使用std::internal中庸之道std::showpos之前(如圖所示here)。

我們需要添加std :: internal標誌來告訴流要插入「內部填充」 - 即填充符應該插入符號和數字的其餘部分之間。

#include <iomanip> 
#include <iostream> 
#include <sstream> 

int main() 
{ 
    std::ostringstream stream; 

    stream << std::setfill('0'); 
    stream << std::setw(3); 
    stream << std::internal; 
    stream << std::showpos; 
    stream << 1; 

    std::cout << stream.str(); // Output: "+01" 
    return 0; 
} 
8

填充字符用於與任何類型來填充一個給定的寬度。默認情況下,填充字符位於值的左側,這就是您看到的那些零。解決的辦法是重寫默認並告訴流把填充字符文:

std::cout << std::internal << std::setfill(0) << std::setw(3) << 1 << '\n'; 

您還可以使用std::leftstd::right把填充字符的值或右左的價值。