2017-10-13 24 views
-1

im爲我的計算機科學課程建立一個簡單的銀行賬戶程序,它讀取一個文件並輸出記錄(c-創建,y-信用賬戶,d-借方賬戶,t交易,r-只在肯定時才刪除) 由這其中工程這個例子的程序:爲什麼在這個例子中我有分段錯誤(核心轉儲),但在第一個不是?

c Ann y 
c Bob n 
c Carl y 
t Ann +200.00 
t Bob -50.0 
t Carl -20.05 
t Dan +1000.0 
r Carl 
t Bob +30.0 
r Ann 
c Bob y 

和輸出:

error on line 5: account cannot hold negative balance 
error on line 7: account does not exist 
error on line 8: account holds negative balance 
error on line 11: account already exists 

Bob owns 30 euros 
Carl owes 20.05 euros 

但對於這個例子:

c Ann y 

c Bob n 

t Ann +534.50 

t Bob +40.00 

t Bob -45.99 

t Ann -200.00 

c Carl y 

c Dan y 

c Eric n 

t Ann -94.99 

t Dan +94.99 

t Carl -20.00 

t Dan +20.00 

r Carl 

c Bob y 

t Dan -15.00 

t Eric +15.00 

r Dan 

t Eric -5.00 

t Bob +5.00 

t Ann -139.51 

t Bob +69.75 

t Carl +69.75 

r Eric 

r Dan 

它輸出:

error on line 5: account cannot hold negative balance 
error on line 14: account holds negative balance 
error on line 15: Account already exists 
error on line 19: account cannot hold negative balance 
Segmentation fault (core dumped) 

下面是代碼:

#include <iostream> 
#include <fstream> 
#include <string.h> 
#include <vector> 
#include <stdexcept> 

void error(std::string str) 
{ 
    throw std::runtime_error(str); 
} 

class Account 
{ 
    private: 

     float money;    
     char type, name[15];   

    public: 

     Account(char t, const char* n); 
     char* getName(); 
     float getMoney(); 
     void setMoney(float m); 
     char getType(); 

}; 

Account::Account(char t,const char* n) 
{ 
    money = 0; 
    type = t; 
    strcpy(name,n); 

} 


float Account::getMoney() 
{ 
    return money; 
} 

void Account::setMoney(float m) 
{ 
    money = m; 
} 

char Account::getType() 
{ 
    return type; 
} 

char* Account::getName() // get name of the account 
{ 
    return name; 
} 

Account* getAccount(std::vector <Account> &allAccounts, std::string name) // in needed reference here so i didnt need to create another function to copy 
{ 
    for(int i = 0; i < allAccounts.size(); i++) // goint through the accounts 
     if(strcmp(allAccounts[i].getName(), name.c_str()) == 0) 

      return &allAccounts[i]; 
    return NULL; 
} 

int getAccountIndex(std::vector <Account> allAccounts, std::string name) // Assumes the account exists in vector 
{ 
    for(int i = 0; i < allAccounts.size(); i++) 
     if(strcmp(allAccounts[i].getName(), name.c_str()) == 0) 

      return i; 
} 

int main() 
{ 
    int line = 0; 
    std::ifstream in("accounts.txt"); 
    std::vector <Account> allAccounts; 

    while(true) 
    { 
     line++; 
     char cmd; 
     in >> cmd; 

     if(in.eof()) // end of file. If it's empty, theres no reason to go through the loop 
     { 
      std::cout << std::endl; 
      break; 
     } 

     std::string name; 
     in >> name; 

     switch(cmd) 
     { 

      case 'c': 

       char type; 
       in >> type; 
       try 
       { 
        if(getAccount(allAccounts,name) != NULL) 
        { 
         error("Account already exists"); 
        } 
        Account a(type, name.c_str()); 
        allAccounts.push_back(a); 

       } 
       catch(std::runtime_error& error) 
       { 
        std::cerr << "error on line " << line <<": "<< error.what() << std::endl; 
       } 
       break; 

      case 't': 
      { 

       float sum; 
       in >> sum; 

       Account* pa = getAccount(allAccounts,name); // assign in memory 

       try 
       { 
        if(pa == NULL) 
        { 
         error("account does not exist"); 
        } 

        if(pa->getType() == 'n' && sum < 0) 
        { 
         error("account cannot hold negative balance"); 
        } 
        pa->setMoney(pa->getMoney() + sum); 
       } 

       catch(std::runtime_error& error) 
       { 
        std::cerr << "error on line " << line <<": "<< error.what() << std::endl; 
       } 

       break; 
      } 

      case 'r': 

       Account* pa = getAccount(allAccounts,name); 
       int i = getAccountIndex(allAccounts,name); 
       try 
       { 
        if(pa->getMoney() < 0) 
        { 
         error("account holds negative balance"); 
        } 

        allAccounts.erase(allAccounts.begin()+i); 

       } 

       catch(std::runtime_error& error) 
       { 
        std::cerr << "error on line " << line <<": "<< error.what() << std::endl; 
       } 
     } 
    } 

    for(int i = 0; i < allAccounts.size();i++) 
    { 
     Account a = allAccounts[i]; 

     std::cout << a.getName() << " "; 
     if(a.getMoney() > 0) 
     { 
      std::cout << "owns " << a.getMoney() << " Euros" << std::endl; 
     } 

     else 
     { 
      std::cout << "owes " << -a.getMoney() << " Euros" << std::endl; 
     } 
    } 

    return 0; 
} 

謝謝您的時間!

+0

乍一看,我發現'getAccount'可以返回NULL,但是你的一些代碼假定它永遠不會返回NULL。 –

回答

0
  Account* pa = getAccount(allAccounts,name); 
      int i = getAccountIndex(allAccounts,name); 
      try 
      { 
       if(pa->getMoney() < 0) 
       { 
        error("account holds negative balance"); 
       } 

       allAccounts.erase(allAccounts.begin()+i); 

      } 

      catch(std::runtime_error& error) 
      { 
       std::cerr << "error on line " << line <<": "<< error.what() << std::endl; 
      } 

有沒有檢查是否paNULLpa->getMoney()之前。所以你在r Dan一線爆炸。您不能在除有效對象之外的任何其他任何地方調用成員函數。

+0

OMG謝謝你,你救了我的命!我一直在尋找小時,我的最後期限是在1小時內。謝謝!!! – Edward

+2

@Edward您需要了解如何使用調試器。驗屍調試與等待程序崩潰然後查看堆棧和變量一樣簡單。 –

+0

是的,這是我在計算機科學課的第7周,我還是個初學者。 – Edward

相關問題