我的代码中除以零

发布于 2024-07-14 05:09:23 字数 3910 浏览 5 评论 0原文

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

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

我的问题是我无法弄清楚我必须做什么来解决问题。 我读了评论,但我仍然很困惑。

Hes my code and I can't figure out where I'm getting the divide by zero problem.

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

My problem is that I am unable to figure out what I have to do to fix the problem. I have read the comments and I am still confused.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

海未深 2024-07-21 05:09:23

您正在分配(并复制!)一个由 Mreview 对象组成的向量,所有这些对象都是使用默认构造函数构建的,因此 numRatings 默认值为 0,并且您没有采取任何措施来确保永远不会在未修改的对象上调用 aveRating() 或至少保护其自身免受 numRatings 为 0 的影响。

编辑:最简单的修复:

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

IMO,进一步的修复方法是将 Mreview 指针(最好是shared_ptr)存储在向量中,并new它们第一个分数将被添加而不是更早添加。

You're allocating (and copying!) a vector of Mreview objects, all of which are being constructed with the default ctor, so numRatings defaults to 0, and you are doing nothing to ensure that aveRating() is never called on unmodified objects or at the very least protects itself from numRatings being 0.

Edit: Easiest fix:

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

A further fix, IMO, would be to store Mreview pointers (ideally shared_ptr) in the vector and newing them when the first score is to be added rather than earlier.

悟红尘 2024-07-21 05:09:23

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

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

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

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

Not the divide by zero error, but...

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

You are taking two integer values and storing it in a double without typecasting... you have to cast either totalScore or numRatings to a double like:

double Mreview::aveRating() const
{
    double rating = (double)totalScore/numRatings;
    return rating;
}
始终不够 2024-07-21 05:09:23

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

When looking for divide by zero problems, look for / and % operators. I see only one / in your code.

岁月无声 2024-07-21 05:09:23

我只看到一个实际的除法运算...

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

...所以它在那里吗?

I only see one actual division operation...

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

...so is it there?

心凉 2024-07-21 05:09:23

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

Can you run it in a debugger and let it tell you where the trap occurred?

梦开始←不甜 2024-07-21 05:09:23

看起来如果修剪后行的长度为 0,则可以调用 printMrList() 而无需先调用 review.addScore() 。 在这种情况下,printMrList() 会调用 review.aveRating(),它会尝试将 totalScore 除以 numRatings。 这两个值都是 0,因此会出现被零除错误。

It looks like if the length of the line is 0 after trimming, then printMrList() can be called without review.addScore() being called first. In that case, printMrList() calls review.aveRating() which tries to divide totalScore by numRatings. Both of these values are 0, so a divide by zero error occurs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文