C ++转换为货币价值

时间:2014-01-24 06:00:45

标签: c++ currency

关于该计划

我有一个显示菜单的程序。菜单包含一系列项目(字符串)和价格(双重类型值)。该程序没有其他用途,只显示菜单。

问题

当然,默认情况下,double类型值会显示小数。这在这种情况下很有用,因为我们列出了物品的价格;但是,通常价格最初以美元符号($)开头。据我所知, iomanip 标题包含“put_money”& “put_money”函数,但这些做我需要他们做的事情。我需要的是菜单中的每个价格与实际值一起显示美元符号。例如:

我想要的输出是:

Please select an item to purchase:

______________________________________________________

 Item:   Prices:   Item:   Prices:   Item:   Prices:
______________________________________________________

 Water     $100     Milk      $200    Juice     $300
  Wine     $400    Bread      $500    Apple     $600
  Tuna     $700    Steak      $800  Bandage     $900
Med-Kit   $1000    Splint    $1100   Thread    $1200

我当前的节目产生了这个:

Please select an item to purchase:

______________________________________________________

 Item:   Prices:   Item:   Prices:   Item:   Prices:
______________________________________________________

 Water      100     Milk       200    Juice      300
  Wine      400    Bread       500    Apple      600
  Tuna      700    Steak       800  Bandage      900
Med-Kit    1000    Splint     1100   Thread     1200

是否有更有效的方法将美元符号添加到我的所有值,而无需手动添加每个单独的美元符号?我只觉得手动添加它们在一个大项目中可能很乏味(当然不是这样,但可能类似)。

我的代码

#include <iostream>
#include <iomanip>
#include <string>

int main(void) {


unsigned short int width = 10;
unsigned short int prec = 6;

float prices[12] = {100.00, 200.00, 300.00, 400.00, 500.00, 600.00, 700.00, 800.00, 900.00, 1000.00, 1100.00, 1200.00};

std::string items[12] = {"Water", "Milk", "Juice", "Wine", "Bread", "Apple", "Tuna", "Steak", "Bandage", "Med-Kit", "Splint","Thread"};

std::cout << "\nPlease select an item to purchase:\n\n";

std::cout << "_________________________________________________________________\n\n";

std::cout << std::setw(width) << "Item:" << std::setw(width) << "Prices:" <<std::setw(width) << "Item:" <<std::setw(width) << "Prices;" <<std::setw(width) << "Item:" <<std::setw(width) << "Prices:" << "\n";

std::cout << "_________________________________________________________________\n\n";

std::cout << std::setw(width) <<items[0] <<std::setw(width) << prices[0] <<std::setw(width) << items[1] <<std::setw(width) << prices[1] <<std::setw(width) << items[2] <<std::setw(width) << prices[2] << "\n";
std::cout << std::setw(width) <<items[3] <<std::setw(width) << prices[3] <<std::setw(width) << items[4] <<std::setw(width) << prices[4] <<std::setw(width) << items[5] <<std::setw(width) << prices[5] << "\n";
std::cout << std::setw(width) <<items[6] <<std::setw(width) << prices[6] <<std::setw(width) << items[7] <<std::setw(width) << prices[7] <<std::setw(width) << items[8] <<std::setw(width) << prices[8] << "\n";
std::cout << std::setw(width) <<items[9] <<std::setw(width) << prices[9] <<std::setw(width) << items[10] <<std::setw(width) << prices[10] <<std::setw(width) << items[11] <<std::setw(width) << prices[11] << "\n";

std::cin.get();
std::cin.get();

return 0;



}

请原谅代码的长度过长。感谢大家提前帮忙。

2 个答案:

答案 0 :(得分:4)

为什么不创建class来存储商品? 例如,您可以:

class Item
{
    private:
    double price;
    string item;

    public:
    void display()
    {
        cout << "$" << price;
    }
};

因此,您调用display函数以货币价值显示价格。

答案 1 :(得分:3)

实际上,std::put_money可以而且将会完全按照的要求正确地使用它。

这有两个部分。首先,您必须选择一个区域设置。默认的“C”语言环境根本不定义要使用的货币符号。通常,您需要使用无名语言环境,如下所示:

std::cout.imbue(std::locale(""));

这会选择(并使用)用户为其配置环境的区域设置,因此(例如)典型的美国用户将获得一些美元符号作为货币符号的美国英语区域设置,但典型的德国用户将获取带有欧元符号的德语区域设置作为货币符号 1 。这也会影响数字的格式。下面的示例输出显示它使用逗号作为千位分隔符和句点(句点)作为小数分隔符。许多欧洲国家的用户(例如)应该期望这两者被颠倒过来。

然后,您需要为流设置showbase标志。对于其他数字,这会告诉流将数字的基数显示为已转换,因此(例如)如果以十六进制打印出某些内容,则会先显示0x(或0X )。当你写钱时,会重新说明是否显示货币符号。

您通常希望将其与您已经收到的有关创建类(或结构)的建议相结合,以存储有关项目的数据。而不是名为display的函数,我会创建一个operator<<的重载来显示项目。

请注意,货币值存储为long double s。在典型的情况下,它将被存储为正常使用中货币的最小面额的整数(例如,在美国,整数个便士)。因此,初始化为100.0实际上意味着值$1.00 2

使用它(并省略了标题的代码),创建和显示表可能如下所示:

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

unsigned short int width=10;
unsigned short int prec=6;

class item {
    std::string name;
    long double price;

public:
    item(std::string const &name, double price): name(name), price(price) {}

    friend std::ostream &operator<<(std::ostream &os, item const &i) {
        return os<<std::setw(width) << i.name
                 <<std::setw(width) << std::showbase << std::put_money(i.price);
    }
};

int main(void) {
    std::vector<item> items {
        {"water", 10000},
        {"Milk", 20000},
        {"Juice", 30000},
        {"Wine", 40000},
        {"Bread", 60000},
        {"Apple", 70000},
        {"Tuna", 80000},
        {"Steak", 90000},
        {"Bandage", 100000},
        {"Med-Kit", 110000},
        {"Splint", 120000},
        {"Thread", 130000}
    };

    std::cout.imbue(std::locale(""));

    unsigned count=0;

    for (auto &&item:items) {
        std::cout<<item;
        if (++count==3) {
            std::cout<<"\n";
            count=0;
        }
    }
}

结果:

    water   $100.00      Milk   $200.00     Juice   $300.00
     Wine   $400.00     Bread   $600.00     Apple   $700.00
     Tuna   $800.00     Steak   $900.00   Bandage $1,000.00
  Med-Kit $1,100.00    Splint $1,200.00    Thread $1,300.00

如果您决定自己进行格式化,请注意它不会像在要写入的项目之前插入$那么简单。问题是你几乎需要在写出值时明确设置宽度和精度。当你这样做时,你会很快发现$插入之前填充数字的填充,所以(例如)你的第一个条目最终会看起来像这样:< / p>

    water$    100.00

...而不是将货币符号放在您几乎肯定想要它的数字旁边。有足够的额外工作可以防止这种情况:

std::ostringstream temp;

temp << '$' << std::setprecision(your_precision) << value;

std::cout << std::setw(your_width) << temp.str();

尽管使用std::put_money使用get_money的工作量比你想要的要多得多,但是当你的格式化得非常接近自己的正确时,它可能会更加有效。仍然(并且为国际化添加甚至最小的支持也是相当多的工作)。


  1. 请注意,虽然符号是根据用户的区域设置自动选择的,但是没有尝试转换该值,因此如果我输入1美元,则该值显示在德语区域,它将显示为1欧元(反之亦然)。
  2. 从技术上讲,我不相信标准实际上需要这个,但是我看到的所有编译器实际上都是这样做的。该标准确实要求put_money$100.00是对称的,因此如果用户输入get_money并使用put_money读取它,请存储生成的内容,然后将其写回使用$100.00时,您应该获得{{1}}作为结果。