2016-01-22 77 views
0

我實際上在學習C++編程語言(我從來沒有編程過),我試圖解決一個問題,我必須設計和實現一個簡單的錢類來計算涉及美元。作者給了我一些關於如何實現這個類的規則:初學者練習:設計一個Money類

  • 在一個long int中表示貨幣數量爲美分數。
  • 對於輸入和輸出表示以美元和美分爲單位的結果,例如16.45
  • 算術運算需要使用4/5舍入規則精確到最後一個分數。

在編碼之前做了一些研究之後,我發現不推薦對貨幣數量使用雙重類型,我應該使用整數。我的問題是關於如何讀取double作爲輸入並將其轉換爲long int而不丟失數據?我應該使用其他方式來做到這一點嗎?我應該直接將long int(代表cents)作爲構造函數參數嗎?我一直在尋找,但是我發現了很多關於數據丟失的信息,這些信息讓我感到困惑。這是一個初學者練習,所以我不認爲這個計算應該非常精確。謝謝

+6

一旦你閱讀**雙**,你已經失去了數據。通常情況下,您可以將它「四捨五入」(典型方法是乘以100,然後將其四捨五入爲整數)。您應該這樣做,或者以字符串的形式讀取,並將它自己解析爲無損數據模型。 – MariusSiuram

回答

1

我們假設輸入格式良好。

也就是說,您收到的所有貨幣金額將在

99.99 

形式,其中9符號可以是0到9之間的任意數字。在小數點的左邊,只有數字,範圍將足夠小以便存儲在int內。

小數點右側(並且總是有小數點)始終是一個正數,也適用於int

您可以創建一個非常簡單的結構來表示的貨幣金額,分離塊錢到一個int,並美分到另一個:

struct Money 
{ 
    int dollars; 
    int cents; 
}; 

在量讀書,你首先會在dollars場讀取。然後你會閱讀.。然後你會在cents場閱讀:

Money m; 
char c; 
std::cin >> m.dollars >> c >> m.cents; 

Live Demo

你有這麼多想通了之後,你就可以開始讓你的I/O更強勁,操控那裏沒有小數點的情況下,或者有人投入了很多。在這一點上,它可能是合理的第一次讀入std::string讓你的錢的文字表述,並從那裏解析string

Money m{0,0}; 
std::string text; 
std::getline(std::cin, text); 
std::cout << "Input was: " << text << std::endl; 

// is there a decimal point? 
size_t decimal_point_position = text.find_first_of('.'); 
m.dollars = stoi(text.substr(0, decimal_point_position)); 
if (decimal_point_position != std::string::npos) 
{ 
    decimal_point_position += 1; 
    m.cents = stoi(text.substr(decimal_point_position, text.size() - decimal_point_position)); 
} 

Demo2

並從那裏你可以繼續提高輸入的健壯性。如果有兩位小數呢?如果輸入中有字符怎麼辦?

我建議你寫幾個測試來測試儘可能多的輸入可能性,假設最愚蠢的,大多數計算機不識字的用戶。你應該如何處理無效輸入?請求更多,拋出異常,使用默認值並打印警告?所有這些都是您將來在處理用戶輸入時做出的決定。

編輯: 爲了解決您的最後一點

算術運算需要精確到使用4/5四捨五入規則的最後一分錢。

這一般不會太困難,只是單調乏味。你遇到的最大障礙將是分裂。在這一點上,你需要非常小心整數舍入。即:

2/1將產生0,而不是0.5

乘法和除法操作不應該執行,因爲它們沒有意義。搜索網頁,瞭解如何使用整數除法精確進行圓整。

+0

獲得更高級之後,您可能需要查看'std :: ratio' [http://en.cppreference.com/w/cpp/numeric/ratio/ratio]以將「cents」部分表示爲分數的100. – AndyG

+0

非常感謝你。我在理解如何實施課程時遇到了一些問題,您的答案對我有很大的幫助。我無法理解如何用一個long int變量來實現所有東西,但正如我所看到的,您的解決方案對我來說是最好的。我認爲作者可以在書中更清楚他的問題陳述。 –