2009-02-27 5 views
1

Hes mein Code und ich kann nicht herausfinden, wo ich das Problem mit der Division durch Null bekomme.Mit einer Division durch Null in meinem Code

mreviewApp.cpp

const int SIZE = 80; 
const char DELIMIT = '|'; 

void parseLine(const char line[], string& title, int& rating); 
void stringTrim(char st[]); 
void printMrList(std::vector <Mreview> mrList); 
Mreview searchTitle(std::vector <Mreview> &mrList, string title); 


int main() 
{ 
    ifstream fin; 

    fin.open("rating_list.txt"); 
    if (fin.fail()) { 
    cerr << "Input file opening error.\n"; 
    exit(1); 
    } 

    char line[SIZE]; 
    string title; 
    int rating; 
    int lineCount = 0; 

    std::vector <Mreview> mrList; 

    /* Process one line at a time */ 
    // Read the first line 
    fin.getline(line, SIZE); 
    stringTrim(line); 

    // Process loop 
    while (strlen(line) != 0) { 
    parseLine(line, title, rating); 
    lineCount++; 

    Mreview review = searchTitle(mrList, title); 
    review.addScore(rating); 

    // Read the next line 
    fin.getline(line, SIZE); 
    stringTrim(line); 
    } 

    cout << "** PROCESS DONE. There were " << mrList.size() << " movie titles. **\n\n"; 

    printMrList(mrList); 
    // Close the input file before exit. 
    fin.close(); 

    system("Pause"); 
    return 0; 
} 

void parseLine(const char line[], string& title, int& rating) 
{ 
    char s[SIZE], r[SIZE]; 
    const char *ptr, *temp1; 
    char *temp2; 

    ptr = strchr(line, DELIMIT); 

    if (ptr != NULL) { 
    // First grab the title string (until '|'). 
    temp1 = line; 
    temp2 = s; 
    while (temp1 != ptr) 
     *temp2++ = *temp1++; 

    *temp2 = '\0'; 

    stringTrim(s); 
    title = s; 

    // Second grab the rating number 
    temp1 = ptr+1; 
    temp2 = r; 
    while (*temp1 != '\0') 
     *temp2++ = *temp1++; 

    *temp2 = '\0'; 

    stringTrim(r); 
    rating = atoi(r); 
    } 
    else { 
    title = ""; 
    rating = 0; 
    } 
} 

void stringTrim(char st[]) 
{ 
    char* ptr; 

    for (ptr = st; *ptr; ptr++) ; 
    for (ptr--; *ptr == ' ' && ptr >= st; ptr--) ; 
    ptr++; 
    *ptr = '\0'; 

    for (ptr = st; *ptr && *ptr == ' '; ptr++) ; 

    if (*ptr && ptr != st) { 
    char* ptr2; 
    for (ptr2 = st; *ptr; *ptr2++ = *ptr++) ; 
    *ptr2 = '\0'; 
    } 
} 

void printMrList(std::vector <Mreview> mrList) 
{ 
    std::vector<Mreview>::iterator itr; 
    for(itr = mrList.begin(); itr != mrList.end(); itr++) { 
     Mreview review = *(itr); 
     cout << review.getTitle() << "\t\t" << review.getTotalScore() << "\t\t" << review.aveRating() << endl; 
    } 
} 

Mreview searchTitle(std::vector <Mreview> &mrList, string title) 
{ 
    Mreview review (title); 
    std::vector<Mreview>::iterator itr; 
    for(itr = mrList.begin(); itr != mrList.end(); itr++) { 
     Mreview r2d2 = *(itr); 
     if(review.getTitle() == r2d2.getTitle()) 
      return r2d2; 
    } 
    mrList.push_back(review); 
    return review; 
} 

mreview.cpp

Mreview::Mreview(string ttl) 
    : title(ttl), totalScore(0), numRatings(0) {} 

Mreview::Mreview(string ttl, int score) 
    : title(ttl), totalScore(score), numRatings(1) {} 
void Mreview::addScore(int score) 
{ 
    this->totalScore += score; 
    this->numRatings += 1; 
} 

double Mreview::aveRating() const 
{ 
    double rating = totalScore/numRatings; 
    return rating; 
} 

mreview.h

#ifndef MREVIEW_H 
#define MREVIEW_H 

#include <string> 
using namespace std; 

class Mreview 
{ 
public: 
    Mreview(string ttl = "N/A"); 
    Mreview(string ttl, int firstScore); 

    string getTitle() const { return title; } 
    int getTotalScore() const { return totalScore; } 
    int getNumRatings() const { return numRatings; } 

    void addScore(int score); 
    double aveRating() const; 

private: 
    string title; 
    int totalScore; 
    int numRatings; 
}; 

#endif 

Mein Problem i Ich kann nicht herausfinden, was ich tun muss, um das Problem zu beheben. Ich habe die Kommentare gelesen und bin immer noch verwirrt.

+0

Vielleicht wollen Sie die Syntax Ihrer Frage dort reparieren. –

+0

Formatierung aufgeräumt ein wenig –

+0

fragen Jon SKeet oder Scott Hanselman sie haben kein Problem damit –

Antwort

3

Ich sehe nur eine tatsächliche Teilungsoperation ...

double Mreview::aveRating() const { 
    double rating = totalScore/numRatings; 
    return rating; 
} 

... so ist es da?

3

Wenn Sie nach Division durch Null suchen, suchen Sie nach den Operatoren/und%. Ich sehe nur einen/in deinem Code.

2

Können Sie es in einem Debugger ausführen und es Ihnen sagen, wo der Trap aufgetreten ist?

3

Nicht die Division durch Null-Fehler, aber ...

double Mreview::aveRating() const 
{ 
    double rating = totalScore/numRatings; 
    return rating; 
} 

Sie nehmen zwei Integer-Werte und es in einem Doppel ohne Schublade gesteckt zu speichern ... Sie haben entweder totalScore oder NUMRATINGS zu einem Doppel werfen wie:

double Mreview::aveRating() const 
{ 
    double rating = (double)totalScore/numRatings; 
    return rating; 
} 
6

Sie Zuweisen (und Kopieren!) einen Vektor von Mreview Objekte, alle mit dem Standard ctor, so numRatings automatisch auf 0 gebaut werden, und Sie sind nichts zu tun, um sicherzustellen, dass aveRating() nie auf unveränderte Objekte oder zumindest schützt sich selbst vor numRatings genannt wird 0.

Edit: Einfachste fix:

double Mreview::aveRating() const { 
    if (numRatings == 0) 
     return 0.; 
    else 
     return static_cast<double>(totalScore)/numRatings; 
} 

Eine weitere Lösung, IMO, wäre zu speichern MreviewZeiger (idealerweise shared_ptr) in den Vektor und new ing sie , wenn die erste Punktzahl hinzugefügt werden soll eher als früher.

+0

Ich bin nur verwirrt, wie genau dieses Problem zu beheben ist. –

+0

Tu Pauls Vorschlag. Das ist die einfachste Lösung. Persönlich würde ich diese Art von Klasse nicht in einem Vektor ohne Zeiger speichern: Ich würde den Standard-Ctor explizit machen und nur eine neue Instanz der Klasse zum Vektor hinzufügen, wenn ich einen ersten Eintrag habe. – greyfade

+0

Er, eher, Pauls Vorschlag testing numRatings anstelle von totalScore. Es tut uns leid. – greyfade

1

Es sieht so aus, als ob die Länge der Zeile nach dem Trimmen 0 ist, dann kann printMrList() aufgerufen werden, ohne dass zuerst review.addScore() aufgerufen wird. In diesem Fall ruft printMrList()review.aveRating() auf, das versucht, totalScore durch numRatings zu teilen. Beide Werte sind 0, daher tritt ein Fehler durch Division durch Null auf.

Verwandte Themen