C ++:当满足循环条件时程序崩溃

时间:2015-09-03 15:56:59

标签: c++ class while-loop crash conditional-statements

我有一个程序,根据用户输入从两个不同的类创建对象。如果用户是学生,则将创建学生课程的对象,学生将在该对象中输入他们正在学习的课程。我有一个while循环,询问用户是否要在每次进入课程后进入另一个课程。如果此人键入n,这是应该结束循环的条件,则程序将停止exit code 11

不应该是这种情况。 while循环后有更多行代码,程序不应在循环结束后结束。这是带有问题的while循环的函数:

void createStudent (char student_name[], int student_age)
{
    Student student;

    student.setName(student_name);
    student.setAge(student_age);

    char courses[8];
    char course_loop = ' ';
    int count = 0;

    cout << "What courses are you taking? "
        "(Enter course prefix and number with no spaces):\n\n";

    while (tolower(course_loop) != 'n')
    {
        cout << "Course #" << count + 1 << ": ";
        cin.ignore();
        cin.getline(courses, 9);
        //student.sizeOfArray(); // Increment the array counter if addCourse reports that the array was not full
        student.addCourse(courses, count);

        cin.clear();

        if (student.addCourse(courses, count))
        {
            cout << "\nHave another course to add? (Y/N): ";

            cin.clear();

            cin.get(course_loop);
        }
        else
        {
            cout << "You have exceeded the number of courses you're allowed to enter. Press any ENTER to continue...";
            cin.ignore();
            course_loop = 'n';
        }

        count++;
    }

    cout << student;
    student.printCourseNames();
}

以下是该计划的其余部分:

// main.cpp
//-----------------------

#include <iostream>
#include "Person.h"
#include "Student.h"
using namespace std;

void createStudent(char [], int);
void createPerson(char [], int);

int main()
{
    char name[128], student_check;
    int age;

    cout << "Please state your name and age: \n\n"
         << "Name: ";
    cin.getline(name, 128);
    cout << "Age: ";
    cin >> age;

    cout << "\n\nThanks!\n\nSo are you a student? (Y/N):";
    cin.ignore();
    cin.get(student_check);

    switch (student_check)
    {
        case 'y':
        case 'Y':
            createStudent(name, age);
            break;
        case 'n':
        case 'N':
            createPerson(name, age);
            break;
        default:
            break;
    }
}

// createStudent function with while-loop posted above comes after this in main.cpp

// student.h
// ------------------

#include "Person.h"
#ifndef PA2_STUDENT_H
#define PA2_STUDENT_H


class Student : public Person
{
    public:
        Student();
        bool addCourse(const char*, int);
        void printCourseNames();
        void sizeOfArray();

    private:
        const char* m_CourseNames[10] = {0};
        int array_counter;
};


#endif

// student.cpp
//------------------

#include <iostream>
#include "Student.h"

using namespace std;

Student::Student() : array_counter(0) {}

void Student::sizeOfArray()
{
   array_counter++;
}

bool Student::addCourse(const char* course, int  index)
{
    if (index < 9)
    {
        m_CourseNames[index] = course;
        return true;
    }
    else if (index == 9)
        return false;
}

void Student::printCourseNames()
{
    if (array_counter != 0)
    {
        cout << ", Courses: ";

        for (int count = 0 ; count < 10 ; count++)
            cout << m_CourseNames[count] << " ";
    }
}

我正在使用CLion作为我的IDE,如果有帮助的话。

2 个答案:

答案 0 :(得分:1)

编辑:与该返回相关的错误与缓冲区有关。

您的输入缓冲区char courses[8]不足以处理来自cin.getline(courses, 9)的输入,这会导致cin缓冲区溢出。 cin.clear() hack正在恢复输入流以允许cin.get(course_loop)的输入,但是当函数尝试返回时,异常仍未处理。

char courses[8]更改为char courses[10](以匹配m_CourseNames中的Student数组),它应该可以正常运行。

更新的代码:

void createStudent(char student_name[], int student_age)
{
    Student student;

    student.setName(student_name);
    student.setAge(student_age);

    char courses[10];
    char course_loop = ' ';
    int count = 0;

    cout << "What courses are you taking? "
        "(Enter course prefix and number with no spaces):\n\n";

    while (tolower(course_loop) != 'n')
    {
        cout << "Course #" << count + 1 << ": ";
        cin.ignore();
        cin.getline(courses, 9);
        cin.clear();

        //Removed the duplicate addCourse() call
        if (student.addCourse(courses, count))
        {
            student.sizeOfArray();  //Needed for printCourseNames() functionality
            cout << "\nHave another course to add? (Y/N): ";

            cin.clear();

            cin.get(course_loop);
        }
        else
        {
            cout << "You have exceeded the number of courses you're allowed to enter. Press any ENTER to continue...";
            cin.ignore();
            course_loop = 'n';
        }

        count++;
    }

    cout << student;
    student.printCourseNames();

    return;
}

答案 1 :(得分:1)

您需要添加一个可以将Student对象发送到输出流的函数,例如cout。实现这一目标的方法是定义一个如下函数:

ostream& operator<<(ostream& os, const Student& student)
{
  os << "Name: " << student.name << ", Age: " << student.age << ", Courses: " << student.m_CourseNames;
  return os;
}

此功能允许您使用<<运算符将数据发送到cout类的输出流,如Student。它将输出流作为一个参数,将学生作为另一个参数。它打印学生的信息,然后返回输出流。这样您就可以将操作员链接起来,以便一次打印多条信息。