Ошибка отладочного утверждения C ++: векторный индекс находится вне диапазона - PullRequest
0 голосов
/ 23 сентября 2018

Я создал программу, которая пытается прочитать файл .csv и вычисляет оценки учеников.

Я создал класс Student, а в функции Main - вектор типа Student, чтобы прочитать файл и сохранить данные в объектах.Затем я сохраняю все свои объекты в векторе.

Код работал нормально, пока я не сделал некоторые изменения, чтобы получить путь к файлу от пользователя.Теперь это не работает IDK, почему .. Пожалуйста, посмотрите на код.

Student.h

#include <iostream>
#include <string>
using namespace std;

class student {
public:
    string CMSID, firstname, lastname;
    double quiz1, ass1, ass2, ass3, quiz2, quiz3, oht1, oht2, ESE, aggregate;

    student();
    student(string cmsid, string fn, string ln, double q1, double a1, double a2, double a3, double q2, double q3, double o1, double o2, double ese);
    void calculateAggregate();

};

Students.cpp

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include "students.h"
using namespace std;


student::student() {}

student::student(string cmsid, string fn, string ln, double q1, double a1, double a2, double a3, double q2, double q3, double o1, double o2, double ese) {
    CMSID = cmsid;
    firstname = fn;
    lastname = ln;
    quiz1 = quiz1;
    quiz2 = quiz2;
    quiz3 = quiz3;
    ass1 = a1;
    ass2 = a2;
    ass3 = a3;
    oht1 = o1;
    oht2 = o2;
    ESE = ese;
}
void student::calculateAggregate()
{
    aggregate = ((quiz1 + quiz2 + quiz3)*(10.0 / 30.0) + (ass1 + ass2 + ass3)*(10.0 / 30.0) + (oht1)*(20.0 / 50.0) + (oht2)*(20.0 / 50.0) + ESE * (40.0 / 100.0));

}

int main(int argc, char **argv) {
    string CMSID, firstname, lastname, quiz1, ass1, ass2, ass3, quiz2, quiz3, oht1, oht2, ESE;
    string Name,fileName;

    ifstream gradesFile;

    cout << "Place your file (.csv) in the program's directory." << endl;
    cout << "Make sure that the first two rows of your file does not contain any student's data. " << endl;
    cout << "Enter file name with extension(.csv): " ;

    // taking filepath or filename input from the user
    cin >> fileName;
    gradesFile.open(fileName);

    //declaring vectors of Type Student and type Double to store the objects of students containing their data (names, quizzes etc)
    vector <double> aggregateList;
    vector <student> students;
    student *st;



    //Ignoring the first two rows containing the titles of the columns
    getline(gradesFile, Name);
    getline(gradesFile, Name);

    /// good() returns true if the file is readable and writeable
    while (gradesFile.good()) {
        try {

            getline(gradesFile, CMSID, ',');
            getline(gradesFile, firstname, ',');
            getline(gradesFile, lastname, ',');
            getline(gradesFile, quiz1, ',');
            getline(gradesFile, ass1, ',');
            getline(gradesFile, ass2, ',');
            getline(gradesFile, ass3, ',');
            getline(gradesFile, quiz2, ',');
            getline(gradesFile, quiz3, ',');
            getline(gradesFile, oht1, ',');
            getline(gradesFile, oht2, ',');
            getline(gradesFile, ESE, '\n');
            if (quiz1.compare("") == 0) { // Replacing the empty colums with a 0 to manipulate the data correctly.
                quiz1 = "0";
            }
            if (quiz2.compare("") == 0) {
                quiz2 = "0";
            }
            if (quiz3.compare("") == 0) {
                quiz3 = "0";
            }
            if (ass1.compare("") == 0) {
                ass1 = "0";
            }
            if (ass2.compare("") == 0) {
                ass2 = "0";
            }
            if (ass3.compare("") == 0) {
                ass3 = "0";
            }
            if (oht1.compare("") == 0) {
                oht1 = "0";
            }
            if (oht2.compare("") == 0) {
                oht2 = "0";
            }
            if (ESE.compare("") == 0) {
                ESE = "0";
            }
            // storing the data as student type objects and storing them in the vector <students>
            st = new student(CMSID, firstname, lastname, stod(quiz1), stod(ass1), stod(ass2), stod(ass3), stod(quiz2), stod(quiz3), stod(oht1), stod(oht2), stod(ESE));
            students.push_back(*st);

        }
        catch (invalid_argument) {}
    }
    // Calculating aggregates of all the student objects, and storing them in a separate aggregate list.
    for (int j = 0; j < students.size(); j++) {
        students[j].calculateAggregate();
        aggregateList.push_back(students[j].aggregate);

    }
    // sorting the aggregateList vector to calculate the Grades correctly
    sort(aggregateList.begin(), aggregateList.end());

    //Calculating Deciles (10,20,30 percents and so on) 
    //d1 gives the data item that has 10 percent values below it, d2 has 20 percent values and so on...

    double d1 = aggregateList[ceil(((aggregateList.size() + 1)*(0.1)))];
    double d2 = aggregateList[ceil(((aggregateList.size() + 1)*(0.2)))];
    double d3 = aggregateList[ceil(((aggregateList.size() + 1)*(0.3)))];
    double d4 = aggregateList[ceil(((aggregateList.size() + 1)*(0.4)))];
    double d5 = aggregateList[ceil(((aggregateList.size() + 1)*(0.5)))];
    double d6 = aggregateList[ceil(((aggregateList.size() + 1)*(0.6)))];
    double d7 = aggregateList[ceil(((aggregateList.size() + 1)*(0.7)))];
    double d8 = aggregateList[ceil(((aggregateList.size() + 1)*(0.8)))];
    double d9 = aggregateList[ceil(((aggregateList.size() + 1)*(0.9)))];


    //Giving grades 

    ofstream A, Bplus, B, Cplus, C, Dplus, D, F;
    A.open(fileName + "-A Grades.csv ");
    Bplus.open(fileName + "-Bplus.csv");
    B.open(fileName + "-B Grades.csv");
    C.open(fileName + "-C Grades.csv");
    Cplus.open(fileName + "-Cplus Grades.csv");
    D.open(fileName + "-D Grades.csv");
    Dplus.open(fileName + "-Dplus Grades.csv");
    F.open(fileName + "-F Grades.csv");


    for (int j = 0; j < students.size(); j++) {


        if (A.is_open()) {
            if (students[j].aggregate > d9) A << students[j].CMSID << "," << students[j].firstname << "," << students[j].lastname << "," << students[j].aggregate << endl;

        }
        else cout << "File coudln't be made." << endl;
        if (Bplus.is_open()) {
            if (students[j].aggregate > d7 && students[j].aggregate <= d9) Bplus << students[j].CMSID << "," << students[j].firstname << "," << students[j].lastname << "," << students[j].aggregate << endl;

        }
        else cout << "File coudln't be made." << endl;
        if (B.is_open()) {
            if (students[j].aggregate > d5 && students[j].aggregate <= d7) B << students[j].CMSID << "," << students[j].firstname << "," << students[j].lastname << "," << students[j].aggregate << endl;
        }
        else cout << "File coudln't be made." << endl;
        if (Cplus.is_open()) {
            if (students[j].aggregate > d4 && students[j].aggregate <= d5) Cplus << students[j].CMSID << "," << students[j].firstname << "," << students[j].lastname << "," << students[j].aggregate << endl;
        }
        else cout << "File coudln't be made." << endl;
        if (C.is_open()) {
            if (students[j].aggregate > d3 && students[j].aggregate <= d4) C << students[j].CMSID << "," << students[j].firstname << "," << students[j].lastname << "," << students[j].aggregate << endl;
        }
        else cout << "File coudln't be made." << endl;
        if (Dplus.is_open()) {
            if (students[j].aggregate > d2 && students[j].aggregate <= d3) Dplus << students[j].CMSID << "," << students[j].firstname << "," << students[j].lastname << "," << students[j].aggregate << endl;
        }
        else cout << "File coudln't be made." << endl;
        if (D.is_open()) {
            if (students[j].aggregate > d1 && students[j].aggregate <= d2) D << students[j].CMSID << "," << students[j].firstname << "," << students[j].lastname << "," << students[j].aggregate << endl;
        }
        else cout << "File coudln't be made." << endl;
        if (F.is_open()) {
            if (students[j].aggregate <= d1) F << students[j].CMSID << "," << students[j].firstname << "," << students[j].lastname << "," << students[j].aggregate << endl;
        }
        else cout << "File coudln't be made." << endl;


    }
    A.close();
    B.close();
    Bplus.close();
    C.close();
    Cplus.close();
    D.close();
    Dplus.close();
    F.close();

    system("pause");
    return 0;
}

Я уже искалвеб-сайт для соответствующих ошибок, но не мог понять! Проверьте ошибку здесь.

Ответы [ 2 ]

0 голосов
/ 23 сентября 2018

Вам нужно использовать отладчик.К счастью, поскольку вы используете Visual Studio, это намного приятнее, чем использование GDB.

Если утверждение не выполнено, нажмите «Повторить» во всплывающем окне, что даст вам возможность проверить стек вызовов и значения переменных.

В качестве альтернативы, если вам так проще, вы можете построчно просматривать программу и наблюдать за изменением значений переменных ...

0 голосов
/ 23 сентября 2018

Ошибка вызвана созданием vector с размером n, но с доступом к элементам сверх этого.

a vector x с размером n имеет

x[0], x[1], x[2], ..., x[n-2], x[n-1]

Доступ к x[n], или x[n+1] будет вне диапазона и вызовет ошибку.

ceil(((aggregateList.size() + 1)*(0.9)))

Это выражение, которое может быть равным n для вектора, и может привести к переполнениюпамять

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...