1

他是我的代码,我不知道我在哪里得到除以零的问题。

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

我的问题是我无法弄清楚我必须做些什么来解决这个问题。我已经阅读了评论,但我仍然感到困惑。

4

6 回答 6

6

您正在分配(并复制!)一个Mreview对象向量,所有这些对象都是使用默认 ctor 构造的,因此numRatings默认为 0,并且您没有做任何事情来确保aveRating()永远不会在未修改的对象上调用它或至少保护自身从numRatings0。

编辑:最简单的修复:

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

IMO 的进一步解决方法是将Mreview 指针(理想情况下为 shared_ptr)存储在向量中,并在添加第一个分数时而不是更早地添加new它们。

于 2009-02-27T04:19:20.140 回答
3

我只看到一个实际的除法操作......

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

……那里有吗?

于 2009-02-27T04:09:33.003 回答
3

在寻找除以零问题时,寻找 / 和 % 运算符。我在您的代码中只看到一个 / 。

于 2009-02-27T04:11:25.823 回答
3

不是除以零错误,而是...

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

您正在获取两个整数值并将其存储在一个 double 中而不进行类型转换......您必须将 totalScore 或 numRatings 转换为一个 double,例如:

double Mreview::aveRating() const
{
    double rating = (double)totalScore/numRatings;
    return rating;
}
于 2009-02-27T04:16:00.837 回答
2

你能在调试器中运行它并让它告诉你陷阱发生在哪里吗?

于 2009-02-27T04:13:36.440 回答
1

看起来如果修剪后线的长度为0,则printMrList()可以在不review.addScore()先调用的情况下调用。在这种情况下,尝试除以的printMrList()调用。这两个值都是 0,因此会发生除以零错误。review.aveRating()totalScorenumRatings

于 2009-02-27T04:23:24.703 回答