C ++:使用嵌套的if / else语句对while循环进行故障排除

时间:2016-02-13 03:03:18

标签: c++ if-statement while-loop sentinel

我正在学习C ++并且有一些问题。

此程序应获取项目名称和价格的输入,并将其输出到文本文件。当为项目名称输入标记值999时,while循环应该停止并输出所有输入集(项目名称和价格)到文本文件。

我对这个程序有两个问题:

  1. 仅显示最新的输入集(名称,价格)。如何将所有输入保存在内存中?

  2. 输入999作为项目名称不会导致程序退出。相反,程序停止显示提示。如何正确停止程序?

  3. 我应该使用for循环,但我不确定如何实现。

    #include <iostream>
    #include <string>
    #include <fstream>
    
    using namespace std;
    
    int main()
    {
        string item_name;
        double price;
        int item_number;
    
        const string SENTINEL = "999";
    
        ofstream myfile ("invoice1.txt");
    
    
        while(item_name != SENTINEL)
        {
            cout<<"Enter the name of the item."<<'\n';
            cin>>item_name;
    
            if (item_name == SENTINEL)
            {
                cin>>item_name;
                myfile<<"Thank you for your entries"<<'\n';
                myfile<<item_name<<"#"<<price<<endl;
                myfile.close();
    
                break;
            }
            else
            {
                cout<<"Enter the price of the item."<<'\n';
                cin>>price;
            }
        }
    
        myfile<<"Thank you for your entries"<<'\n';
        myfile<<item_name<<"#"<<price<<endl;
        myfile.close();
    
        return 0;
    }
    

2 个答案:

答案 0 :(得分:0)

如何使用std::vector

执行此操作

首先,一些包括:

#include <vector> // obviously. Can't do vectors without the vector header.
#include <limits> // for a trick I'll use later

创建一个结构,将项目名称与价格

相关联
struct item
{
    string name;
    double price;
};

并制作该结构的载体

vector<item> items;

然后,在您阅读了名称和价格后,将其填入结构中并将结构填充到矢量中。

item temp;
temp.name = item_name;
temp.price = price;
items.push_back(temp);

关于为什么while循环不起作用......我们将会一直走过去。

while(item_name != SENTINEL)

这是一个好的开始。如果item_name不是SENTINEL,请继续。非常正确。事情是,第一次到达这里时,项目名称没有被设置,在循环中强制一些松散的逻辑。阅读一般经验法则,然后进行测试。阅读前的测试不是那么有用。首先,没有什么可以测试的,但真正的问题是你现在正在使用未经测试的数据,或者必须包含另一个测试才能捕获它。

阅读,然后测试。

{
    cout<<"Enter the name of the item."<<'\n';
    cin>>item_name;

获取商品名称。 Groovy的杂交。

    if (item_name == SENTINEL)
    {
        cin>>item_name;

行。不错,但为什么在这里得到另一个item_name?

        myfile<<"Thank you for your entries"<<'\n';
        myfile<<item_name<<"#"<<price<<endl;
        myfile.close();

        break;

break退出循环或switch。我们走了。

    }
    else
    {
        cout<<"Enter the price of the item."<<'\n';
        cin>>price;

读取数值有一些危险你必须注意。最重要的一点是,如果用户输入的内容无法转换为pricecin将进入错误模式并且无法退出,直到错误被清除。在您尝试再次获得价格之前,需要删除垃圾数据。

关于cin >> x的一个简洁的事情是它返回cin。这使您可以堆叠命令。 cin>>a>>b>>c>>dcin及其所有流媒体兄弟都有一个内置的布尔运算符,可以在测试中使用。如果cin仍然处于良好状态,所有读取都已成功完成,则可以对其进行测试并返回true

这可以让你做if (cin>>a>>b>>c>>d)这样的事情,并测试所有的读取都是一次性的。

    }
}

应用read,然后测试,我们得到

while(cin>>item_name && // read in an item name
      item_name != SENTINEL) // and then test that it isn't the sentinel

这个看起来很狡猾的代码是关于最安全的方法。它甚至会抓住并退出cin突然结束。不会经常使用cin发生这种情况,但这是测试文件结尾的好方法。

{
    while (!(cin >> price)) // keep looping until the user gives a number
    {  // if we're here, the user didn't give a good number and we have to clean up 
       // after them. Bad user. Bad. Bad.

顺便说一句,不要用文件来做这个伎俩。该文件可能已经结束。您必须在文件结束时测试该文件并退出此处,然后再继续进行清理。

        // clear the error
        cin.clear(); 
        // throw out everything the user's typed in up to the next line
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }
    // user got out of the while of doom. They must have entered a number.
实际上,Welllll只需从数字开始。 cin >>非常愚蠢,将1234abcd通过,取1234并留下abcd进行下一次阅读。这可能会给你留下一些令人讨厌的惊喜。在这种情况下,abcd将结束为下一个item_name。应该是下一个item_name将成为下一个price,而那个糟糕的ju-ju将从那里滚动。

现在回到代码。

    item temp; // make a temporary item
    temp.name = item_name; // set the values correctly
    temp.price = price;
    items.push_back(temp); // put them in the list.

您可以通过向item添加构造函数并使用vector的{​​{1}}方法来节省一些工作。仔细看看。非常方便。

emplace_back

再次没有正在运行的评论:

}

现在你有while(cin>>item_name && // read in an item name item_name != SENTINEL) // and then test that it isn't the sentinel { while (!(cin >> price)) // keep looping until the user gives a number { // if we're here, the user didn't give a good number and we have to clean up // after them. Bad user. Bad. Bad. // clear the error cin.clear(); // throw out everything the user's typed in up to the next line cin.ignore(numeric_limits<streamsize>::max(), '\n'); } // user got out of the while of doom. They must have entered a number. item temp; // make a temporary item temp.name = item_name; // set the values correctly temp.price = price; items.push_back(temp); // put them in the list. } vector个要打印的内容。 Stack Overflow充满了关于如何执行此操作的示例,但如果您首先拍摄它是最好的。

答案 1 :(得分:-2)

为什么在检查条目的if语句中有额外的cin调用? 我认为没有必要。

对于输入问题,您只存储最近输入的值,因为每次循环再次运行时,它将覆盖变量。

要解决此问题,您需要使用数组来存储项目。如果你想让它运行循环,你可以根据需要输入多个输入,你需要实现一个动态数组。

以下是如何实现动态数组http://www.learncpp.com/cpp-tutorial/6-9a-dynamically-allocating-arrays/