2014-04-14 13 views
0

我最近開始用C++進行編程,在我的學校,州等地進行比賽。我還沒有做過很多練習,而且我對C++還是比較新鮮的,並且遇到了這個問題在我的程序中,如果輸入的是字符而不是數字值,則循環會連續運行而不詢問輸入。最近有這個節目,我寫信給做基本的化學轉化酒吧:如何更正確地將異常集成到我的代碼和未來的代碼中? (C++)

#include "stdafx.h" 
using namespace std; 
class Exception : public exception 
{ 
public: 
    Exception(string m = "Exception!") : msg(m){} 
    ~Exception() throw() {} 
    const char* what() const throw() { return msg.c_str(); } 

private: 
    string msg; 
}; 
int _tmain(int argc, _TCHAR* argv[]) 
{ // 'n' stands for numerator and 'd' stands for denominator 
    int choice; 
    float n1; 
    float n2; 
    float n3; 
    float n4; 
    float d1; 
    float d2; 
    float d3; 
float answer; 
    while (true) 
     { 
     cout << "Select how many conversion bars you have: " << endl; 
     cin >> choice; 
      if (choice == 1) 
       {cout << "What is the starting number?" << endl; 
       cin >> n1; 
       cout << "What is the first bar (Enter Numerator then Denominator): " << endl; 
       cin >> n2; 
       cin >> d1; 
       answer = n1 * n2/d1; 
       cout << "Answer: " << answer << endl << endl;} 
      else if (choice == 2) 
      { 
       cout << "What is the starting number?" << endl; 
       cin >> n1; 
       cout << "What is the first bar (Enter Numerator then Denominator): " << endl; 
       cin >> n2; 
       cin >> d1; 
       cout << "What is the second bar (Enter Numerator then Denominator): " << endl; 
       cin >> n3; 
       cin >> d2; 
       answer = (n1 * n2 * n3)/(d1 * d2); 
       cout << "Answer: " << answer << endl << endl; 
      } 
      else if (choice == 3) 
      { 
       cout << "What is the starting number?" << endl; 
       cin >> n1; 
       cout << "What is the first bar (Enter Numerator then Denominator): " << endl; 
       cin >> n2; 
       cin >> d1; 
       cout << "What is the second bar (Enter Numerator then Denominator): " << endl; 
       cin >> n3; 
       cin >> d2; 
       cout << "What is the third bar (Enter Numerator then Denominator): " << endl; 
       cin >> n4; 
       cin >> d3; 
       answer = (n1 * n2 * n3 * n4)/(d1 * d2 * d3); 
       cout << "Answer: " << answer << endl << endl; 
      } 
      else if ((choice /= 1) || (choice /= 2) || (choice /= 3)) 
       {cout << "That is not a valid option." << endl << endl;} 
      try{ throw Exception();} 
       catch (exception& e)      
      { 
       cout << e.what() << endl; 
       break; 
      } 
     } 
return 0; 
} 

和頭:

#pragma once 

#include "targetver.h" 
#include <stdio.h> 
#include <tchar.h> 
#include <iostream> 
#include <cstdint> 
#include <cstdbool> 
#include <string> 

那麼我將如何更好地整合例外到這個代碼和任何未來的代碼?例外

+11

這在某種程度上是品味的問題,但在我看來,這不是例外情況。例外情況是出乎意料地發生的事情,很少,_exceptionally_。錯誤的用戶輸入始終發生,並且預期會發生。拋出異常並不是嚴格錯誤(雖然是多餘的),但我認爲這是一個有些尷尬的設計。 – Damon

+0

當你聲明它們時,請開始初始化所有變量!另外,使用名稱空間標準是一個壞習慣,你不應該那樣做。 – crashmstr

+0

1.你會如何建議處理錯誤的用戶輸入, 2.你是什麼意思「初始化」我的變量? (我正在教自己,只是搞亂了代碼) –

回答

1

三條基本規律(當然這更像是一個個人的味道,但也許你會發現有用):

  1. 不要使用控制流異常 - 使用的是控制流語句(如,而)

    //good: 
    while(isValidInput) 
    { 
        // check your validness 
        // e.g. if (atoi(input) != 1) ... 
    } 
    
  2. 不掩飾已經趕上了自己的異常類型的異常(你已經確切地知道什麼是錯的 - 你只會躲在這上層)

    //bad: 
    ... 
    catch(std::ios_base::failure& ex) 
    { 
        throw myDataFormatException("Format error"); 
    } 
    
  3. 使用異常低的水平越好(你是在浪費大量的CPU處理能力,你可以冒險,因爲一切都只是夾在主塊沒有意識到你的程序中新的錯誤)

    //bad: 
    int main() { try { /* everything */ } catch(...) {} }; 
    // good: 
    try 
    { 
        std::ifstream inputFileStream("~/File.txt"); 
    } 
    catch(std::ios_base::failure&) { ... } 
    
+0

C#答案的C + +的問題? – crashmstr

+0

你能解釋一下你的第三個例子嗎?我還沒有遇到那些特定的關鍵字或功能。 –

+2

我很欣賞你的例子有不同的語言,但在C++中,絕不會拋出'new ...'。這將導致內存泄漏,未經處理的例外,嚎,大哭,以及咬牙切齒。 –

0

實際上,對於您遇到的特定問題,您並不需要例外。你需要的是驗證你的輸入。您應該研究std :: cin的文檔,並學習如何測試輸入的成功或失敗 - 請參閱http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/並記下failbit。

+0

好的,我將如何處理failbit?它可以應用在'if'語句中嗎? –

+0

我看着'failbit',但我仍然有一些麻煩。我是否需要在'main()'之外編寫一個函數並將其稱爲測試'failbit'? –

+0

你想測試一下,例如'cin >> n1'後,它還沒有被設置。如果它已經設置,那麼你的提取失敗,你需要reprompt他們。移動你的代碼以提示把這些條轉換成一個函數(注意你連續做了3次完全相同的事情),並且在該函數中嘗試獲取一個數字,如果失敗,則重新提示。 –