2017-10-13 13 views
-1

Im construire un simple compte bancaire pour mon cours de science informatique qui lit un fichier et sort les enregistrements (c-créer, compte y-crédit, compte débiteur, transaction t, r-supprimer seulement si positif) I fait le programme qui qui travaille pour cet exemple:Pourquoi ai-je un défaut de segmentation (core dumped) dans cet exemple mais dans le premier pas?

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 

et sorties:

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 

Mais pour cet exemple:

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 

Il produit:

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) 

Voici le code:

#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; 
} 

Merci pour votre temps!

+0

À première vue, je vois que 'getAccount' peut retourner NULL mais une partie de votre code suppose qu'il ne retournera jamais NULL. –

Répondre

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; 
      } 

Il n'y a pas cocher si pa est NULL avant pa->getMoney(). Donc, vous exploser dans la ligne r Dan. Vous n'êtes pas autorisé à appeler une fonction membre sur autre chose qu'un objet valide.

+0

OMG merci, vous m'avez sauvé la vie !! J'ai cherché des heures et ma date limite est dans 1 heure. Je vous remercie!!! – Edward

+2

@Edward Vous devez alors apprendre à utiliser un débogueur. Le débogage post-mortem est aussi facile que d'attendre que le programme plante, puis de regarder la pile et les variables. –

+0

Ouais, c'est ma 7ème semaine en cours d'informatique, je suis encore un débutant. – Edward