如何使用哨兵触发矢量结束?

时间:2014-07-14 19:29:34

标签: c++ vector

我是编程(一般)和C ++(特别是)的新手。我正在学习向量,我正在尝试编写一个简单的程序:

  1. 允许用户输入学生考试成绩的向量
  2. 当用户键入sentinel(在这种情况下为-1)时,向量终止
  3. 输出学生成绩的统计数据
  4. 这是我的代码:

    #include "stdafx.h"
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    const int SENTINEL = -1;
    
    vector<int> studentGrades = { 0 };
    int myInput;
    
    int main()
    {
        do
        {
            cout << "Please enter a student's grade: ";
            cin >> myInput;
    
            if (myInput < 1000)
            {
                studentGrades[myInput]++;
            }
    
            studentGrades.push_back(myInput);
    
        } while (myInput != SENTINEL);
    
    
        cout << "\n";
    
        for (int i = 0; i < 1000; i++)
            cout << i << " grade(s) of " << studentGrades[i] << endl;
    
        return 0;
    }
    

    两个问题:

    1)任何人都可以提供有关为什么此代码只允许我输入一个学生成绩的指导吗?

    2)计算“计数”的for循环是否正确?

    先谢谢你一起来看看, 莱恩

    *修订后的代码*

    @ JCx - 这是修改后的代码:

    #include "stdafx.h"
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    const int SENTINEL = -1;
    
    vector<int> studentGrades = { 0 };
    int myInput;
    
    int main()
    {
        do
        {
            cout << "Please enter a student's grade (or -1 to QUIT): ";
            cin >> myInput;
    
            if (myInput < 1000)
            {
                studentGrades.at(myInput)++;
            }
    
            studentGrades.push_back(myInput);
    
        } while (myInput != SENTINEL);
    
    
        cout << "\n";
    
        for (int i = 0; i < 1000; i++)
            cout << i << " grade(s) of " << studentGrades.at(myInput) << endl;
    
        return 0;
    }
    

    并且,我看到了这个错误:

    0x7707C42D处的未处理异常

    Microsoft C ++异常:内存位置为0x0035F890的std :: out_of_range

1 个答案:

答案 0 :(得分:0)

不止一个问题。当用户输入您的sentinel值时尝试访问studentGrades [-1],以及默认向量仅包含0的条目和push_back的使用这一事实。

让我们来解决一些问题:

  • 用户运行程序。用户输入100. studentGrades [100]超出范围。由于向量只有一个元素,因此会发生未定义的行为。
  • 用户运行程序,输入-1 studentGrades [-1]超出范围。
  • 用户运行程序,输入0. studentGrades [0]在范围内,递增为1. studentGrades.push_back(1)向向量添加元素studentGrades [1]现在也等于1.

作为一个很好的起点,如果您将下标向量引用替换为 at 方法,如下所示,您将获得超出范围的错误,这将有助于(很多) 。下面的代码仍然需要工作,但至少你会有运行时错误而不是奇怪的行为。

int main()
{
    do
    {
        cout << "Please enter a student's grade: ";
        cin >> myInput;

        if (myInput < 1000)
        {
            studentGrades.at(myInput)++;
        }

        studentGrades.push_back(myInput);

    } while (myInput != SENTINEL);


    cout << "\n";

    for (int i = 0; i < 1000; i++)
        cout << i << " grade(s) of " << studentGrades.at(myInput) << endl;

    return 0;
}

我认为如果我实现这个,我将使用std :: map而不是vector。它会让你有一个studentGrade [1000],而不必先为studentGrade [0]到[999]分配内存。

然而,当您了解std :: vector时,请检查vector :: resize以将矢量设置为足够大的所需元素,std :: vector :: size以确定是否需要增加大小。然后你可以抛弃push_back。

<强>参考

vector :: at http://www.cplusplus.com/reference/vector/vector/at/

vector :: size http://www.cplusplus.com/reference/vector/vector/size/