2017-10-13 94 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把填充字符的值或右左的价值。