C++中cout的十进制对齐

5
我很难将小数值对齐。我相信这是右对齐和setprecision / fixed的组合,但似乎并没有起作用。我知道其他问题已经问过了,但我还没有找到一个清晰的解决方案来使一堆列(唯一的cout语句对齐)。这是我的代码块:
double total_collect, sales, country_tax, state_tax, total_tax;
const double STATE_TAX_RATE = 0.04, COUNTRY_TAX_RATE = 0.02; 

// Compute taxes
total_collect = 100;
sales = 100 / 1.06 ;
country_tax = sales * COUNTRY_TAX_RATE;
state_tax = sales * STATE_TAX_RATE;
total_tax = country_tax + state_tax;

//Display

cout << setiosflags(std::ios::right) ;

cout << "Totla Collected: " << setw(7) << "$ " << fixed << setprecision(2) << right << total_collect << endl;
cout << "Sales: " << setw(17) << "$ "  << fixed << setprecision(2) << right << sales  << endl;
cout << "Country Sales Tax: " << setw(5) << "$ " << fixed << setprecision(2) << right << country_tax  << endl;
cout << "State Sales Tax: " << setw(7) << "$ "  << fixed << setprecision(2) << right << state_tax << endl;
cout << "Total Sales Tax: " << setw(7) << "$ " << fixed << setprecision(2) << left  << total_tax << endl << endl; 

这是它的原貌:
enter image description here 这就是我期望它呈现的效果:
enter image description here
1个回答

2
您正在设置"$"的宽度,这将它们对齐得很漂亮。但您还需要为值本身设置宽度。我在每个固定值前添加了setw(8),这样它们就可以很好地对齐,除了最后一个,它使用的是left而不是right。您可能需要不同的宽度值,但对于每行应该都是相同的。
理想的解决方案是使用std::put_money(根据您的评论,我看到您不能使用它,但也许这会帮助其他人阅读此答案)。我增加了美元金额以说明千位分隔符并修复了一些错误。
#include <locale>
#include <iostream>
#include <iomanip>

int main()
{
    double total_collect, sales, country_tax, state_tax, total_tax;
    const double STATE_TAX_RATE = 0.04, COUNTRY_TAX_RATE = 0.02;
    const auto TAX_WIDTH = 10;
    const auto LABEL_WIDTH = 19;

    // Compute taxes
    total_collect = 10000;
    sales = total_collect / 1.06 ;
    country_tax = sales * COUNTRY_TAX_RATE;
    state_tax = sales * STATE_TAX_RATE;
    total_tax = country_tax + state_tax;

    //Display
    std::cout.imbue(std::locale("en_US.utf8"));
    std::cout << std::setw(LABEL_WIDTH) << std::left << "Total Collected: "
        << std::setw(TAX_WIDTH) << std::right << std::showbase
        << std::put_money(total_collect * 100.0) << std::endl;
    std::cout << std::setw(LABEL_WIDTH) << std::left << "Sales: "
        << std::setw(TAX_WIDTH) << std::right << std::showbase
        << std::put_money(sales * 100.0) << std::endl;
    std::cout << std::setw(LABEL_WIDTH) << std::left << "Country Sales Tax: "
        << std::setw(TAX_WIDTH) << std::right << std::showbase
        << std::put_money(country_tax * 100.0) << std::endl;
    std::cout << std::setw(LABEL_WIDTH) << std::left << "State Sales Tax: "
        << std::setw(TAX_WIDTH) << std::right << std::showbase
        << std::put_money(state_tax * 100.0) << std::endl;
    std::cout << std::setw(LABEL_WIDTH) << std::left << "Total Sales Tax: "
        << std::setw(TAX_WIDTH) << std::right << std::showbase
        << std::put_money(total_tax * 100.0) << std::endl << std::endl;
}

我得到了以下输出:
总共收集:   $10,000.00
销售额:              $9,433.96
国家销售税:    $188.68
州销售税:      $377.36
销售税总额:      $566.04

(注意:原文中的格式已被保留,包括< p >和< pre >标签)

我尝试了你的建议,它起作用了。但我不确定发生了什么。我真的希望$$和金额之间没有空格。使用你的解决方案很好,除非我将美元符号移到变量的右侧,然后它就会出现问题。 - YelizavetaYR
谢谢 - 是的,我知道那个方法,但被告知要在不使用put_money的情况下解决这个问题。难题是如何对齐小数点,使用哪些组合来使字符串/变量与小数金额对齐。 - YelizavetaYR
1
其中的技巧是在对齐之前必须将“$”放在字符串化的美元金额上。为此,我认为您需要使用std::stringstream - Fred Larson
谢谢 - 所以没有干净的方法来对齐这些变量(小数点右对齐),然后将其前面的字符串与变量本身对齐? - YelizavetaYR
你也可以使用 int(val)int(round(val*x))%x 来找到小数点左右的组成部分,其中上面的例子中 x 为 100。(负值需要稍微多做一些工作,并且 LHS 和小数点本身的格式仍应通过区域设置完成。)在我看来,这不太优雅,但它能够产生与货币格式化相同的输出,而不限于可以在区域设置的货币中表示的值。 - John P
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接