简体   繁体   English

需要一些帮助在我的程序中发现逻辑错误

[英]Need some help finding a logic error in my program

I am learning C++ through Bjarne Stroustrup's "Programming Principles and Practices Using C++" second edition. 我正在通过Bjarne Stroustrup的“使用C ++编程原理和实践”第二版来学习C ++。 I am committed to doing all the drills and exercises because I am taking a game AI class in a month at school and I need to know C++ and I want to know as much as possible. 我致力于进行所有的练习和练习,因为我要在一个月内在学校上一门游戏AI课,而且我需要了解C ++,并且我想尽可能地了解。

Anyways, if anyone has ever done the drill in the book, I am on Chapter 4's drill. 无论如何,如果有人曾经做过本书中的练习,那么我就是第4章的练习。 I am at the very end. 我在最后。 The final product is supposed to be a program that takes a number followed by a unit of measurement (cm, in, ft, or m) in a while loop while keeping track of the biggest value as well as the smallest value and total sum of units entered in meters. 最终产品应该是一个程序,该程序在while循环中采用一个数字,后跟一个度量单位(cm,in,ft或m),同时跟踪最大,最小和总和。单位以米为单位。 I am working entirely in meters except for the biggest and smallest values which are converted to meters to check which one is bigger but stored as they were originally entered by the user. 除了将最大值和最小值转换为仪表以检查哪个更大,然后按用户最初输入的值存储之外,我完全用仪表工作。 The numbers are also inserted into a vector which isn't used until the very end to sort the values and print them in order. 数字也插入到向量中,直到最后才对值进行排序并按顺序打印它们。

Anyways, I seem to have no issue keeping track of total meters because it prints out correctly at the end but when it comes to smallest value something seems to go wrong as well as occasionally on the biggest value. 无论如何,跟踪总仪表似乎没有问题,因为它会在末尾正确打印,但是当涉及到最小值时,似乎有时会出现问题,有时还会出现最大值。 Plus, some values are completely off in the vector of values. 另外,某些值在值向量中完全不可用。 I will but the code bellow. 我会在下面的代码。 I think the error is somewhere in my toMeters() but I have stared at it for so long that I feel like a fresh set of eyes might be helpful. 我认为该错误出在我的toMeters()中,但我盯着它看了很长时间,以至于觉得新的一双眼睛可能会有所帮助。 Thanks! 谢谢!

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

constexpr double mToCm = 100.00; //1m == 100cm
constexpr double inToCm = 2.54; //1in == 2.54cm
constexpr double ftToIn = 12.00; //1ft == 12in

//this function just increases total ammount of units in meters
double adder(string unit, double total, double num)
{
    if(unit == "cm")
    {
        total += (num / mToCm);
    }
    else if(unit == "in")
    {
        double temp;
        temp = num * inToCm;
        total += (temp / mToCm);
    }
    else if(unit == "ft")
    {
        double temp;
        temp = num * ftToIn;
        temp *= inToCm;
        total += (temp / mToCm);
    }
    else
    {
        total += num;
    }
    return total;
}

double toMeters(string unit, double num)
{
    double value = num;

    if(unit == "cm")
    {
        value /= mToCm;
    }
    else if(unit == "in")
    {
        value *= inToCm;
        value /= mToCm;
    }
    else if(unit == "ft")
    {
        value *= ftToIn;
        value *= inToCm;
        value /= mToCm;
    }
    return value;
}

int main()
{

    double num, biggest, smallest; //current number, biggest and smallest value
    double total = 0; //total number in meters
    string unit, biggestUnit, smallestUnit; //current unit, unit for biggest and smallest value
    int count = 0; //count for the loop it's only real purpose is on the first and second loop runs
    vector<double>meters; //a vector of doubles called meters


    cout << "Total ammount of units will be converted to meters, largest and biggest values will be kept in original units\n";
    cout << "Start of by entering a number followed by cm, m, in, ft and continue until you want to stop; to stop, press |\n";

    while(cin >> num >> unit)
    {
        //check if user want to stop
        if(num == '|')
        {
            break;
        }

        //check for correct units, if not then break out
        if(unit != "cm" && unit != "m" && unit != "in" && unit != "ft")
        {
            cout << "Unit not recognized; only cm, m, in, ft are valid\n";
            return 1;
        }
        //this checks if there is no second unit but since cin reads no 
        //whitespace it doesn't work. I just haven't gotten around to removing it
        else if(unit == " ")
        {
            cout << "Please input a unit\n";
            return 1;
        }

        //all values in vectors are supposed to be in meters. If the unit is not 
        //in meters, we will call a push back on the value returned by converting 
        //the orignal number to meters
        if(unit != "m")
        {
            meters.push_back(toMeters(unit, num));
        }
        //else, just call a push_back
        else
        {
            meters.push_back(num);
        }

        //if the count is 0, i.e. very first run of the program, biggest and 
        //smallest is equal to original and call adder() to increment the total
        if(count == 0)
        {
            biggest = smallest = num;
            biggestUnit = smallestUnit = unit;

            total = adder(unit, total, num);
        }
        //else, if count is > 0, i.e. this is not the first run, do this part
        else
        {   
            //if the value returned after running toMeters on the current value
            //is greater than the biggest, biggest now equals current num and 
            //biggest unit is equal to current unit. Then call adder to inceare total
            if(toMeters(unit, num) > toMeters(biggestUnit, biggest))
            {
                biggest = num;
                biggestUnit = unit;

                total = adder(unit, total, num);
            }
            //same as top function but for smallers value
            else if(toMeters(unit, num) < toMeters(smallestUnit, smallest))
            {
                smallest = num;
                smallestUnit = unit;

                total = adder(unit, total, num);
            }
            //else both numbers are equal so just make a call to adder()
            else
            {
                total = adder(unit, total, num);
            }
        }
        //increase count just because. It was really only needed to be incremented once 
        ++count;
    }

    //call sort on the vector then print out the total units followed by bigges the smallest values
    //then the values in meters, is ascending sorted order.
    sort(meters.begin(), meters.end());
    cout << "Total units in meters is " << total << "\n";
    cout << "Largest unit is " << biggest << biggestUnit << "\n";
    cout << "Smallest unit is " << smallest << smallestUnit << "\n";
    cout<< "Here are all values you entered, in meters, in ascending order: \n";

    for(int i : meters)
    {
        cout << meters[i] << "m" << " ";
    }
    cout << "\n";
}

My latest inputs were 1 cm 2 in 3 m 4 ft and the output was Total units in meters is 4.28 Largest unit is 3m (correct) Smallest unit is 2in (should be 1cm) Here are all values you entered, in meters, in ascending order: 0.01m 0.01m 0.0508m 3m 我最近的输入是3 m 4 ft中的1 cm 2,输出是米的总单位是4.28最大单位是3m(正确)最小单位是2in(应该是1cm)这是您输入的所有值(以米为单位)订单:0.01m 0.01m 0.0508m 3m

You don't set biggestUnit or smallestUnit when you set biggest and smallest on the first input. 当您在第一个输入上设置biggestsmallest biggestUnit您没有设置biggestUnitsmallestUnit So the comparisons don't work correctly. 因此,比较无法正常进行。

Try: 尝试:

    //if the count is 0, i.e. very first run of the program, biggest and 
    //smallest is equal to original and call adder() to increment the total
    if(count == 0)
    {
        biggest = smallest = num;
        biggestUnit = smallestUnit = unit;

        total = adder(unit, total, num);
    }

Also, it's not a good idea to put total = adder(unit, total, num); 另外,将total = adder(unit, total, num);也不是一个好主意total = adder(unit, total, num); in every code path. 在每个代码路径中。 Just place it once outside the if s. 只需将其放置在if s外部即可。 Otherwise, it's harder to see that it is always executed precisely once for each input. 否则,很难看到每个输入总是精确地执行一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM