Оператор перегрузки = ошибка чтения строки

0

Я пытаюсь написать перегрузку для оператора = так, чтобы он позволял вам напрямую назначать один объект-ученик другому объекту-ученику. Таким образом, он скопирует все личные данные. Вот что я до сих пор.

.час

#ifndef PROJECT3HEADER_H
#define PROJECT3HEADER_H

#include <iostream>
#include <fstream>
#include <string>

using namespace std;
class Student
{
public:
 Student();


void Setlname(string lname);
void Setfname(string fname);
void SetAverage(float Average);
void SetLettergrade(char lettergrade);
void SetTestScore1(float score1);
void SetTestScore2(float score2);
void SetTestScore3(float score3);
void SetTestScore4(float score4);
void SetTestScore5(float score5);

string Getlname()const;
string Getfname()const;
float GetAverage()const;
char GetLetterGrade()const;
float GetScore1()const;
float GetScore2()const;
float GetScore3()const;
float GetScore4()const;
float GetScore5()const;

//void operator = (const Student & rhs);
Student operator=(const Student &rhs);

 private:
string lname,fname;
 float testScore[5];
float Average;
char lettergrade;
};
ostream & operator << (ostream &, const Student & pt);
//istream& operator >> (istream& in, Student& pt);

#endif

Studentmem.cpp

#include "Project3Header.h"

#include <iostream>
#include <string>

using namespace std;

Student::Student()
{
  lname="";
  fname="";
  Average=0;
  lettergrade=' ';
  testScore[0]=0,testScore[1]=0,testScore[2]=0,testScore[3]=0,testScore[4]=0;
      }
      void Student::Setlname(string lname1){
    lname=lname1;
  }
  void Student::Setfname(string fname1){
    fname=fname1;
  }
  void Student::SetAverage(float average1){
    Average=average1;
  }
  void Student::SetLettergrade(char lettergrade1){
    lettergrade=lettergrade1;
  }
  void Student::SetTestScore1(float score1){
    testScore[0]=score1;
  }
  void Student::SetTestScore2(float score2){
    testScore[1]=score2;
  }
  void Student::SetTestScore3(float score3){
    testScore[2]=score3;
  }
  void Student::SetTestScore4(float score4){
    testScore[3]=score4;
  }
  void Student::SetTestScore5(float score5){
    testScore[4]=score5;
  }

  string Student::Getlname()const {
    return lname;
  }
  string Student::Getfname()const {
    return fname;
  }
  float Student::GetAverage() const{
    return Average;
  }
  char Student::GetLetterGrade()const{
    return lettergrade;
  }
  float Student::GetScore1() const{
    return testScore[0];
  }
  float Student::GetScore2() const{
    return testScore[1];
  }
  float Student::GetScore3() const{
    return testScore[2];
  }
  float Student::GetScore4() const{
    return testScore[3];
  }
  float Student::GetScore5() const{
    return testScore[4];
  }
 Student Student::operator=(const Student &rhs){
    lname = rhs.lname;
    fname = rhs.fname;
    for (int i = 0; i < 5; i++){
        testScore[i] = rhs.testScore[i];
    }
    return *this;
}

std::ostream& operator<<(std::ostream& out, Student const& obj)
 {
out << "Lname: " << obj.Getlname() << "\n";
out << "fname: " << obj.Getfname() << "\n";
out << "Average: " << obj.GetAverage() << "\n";
out << "Grade: " << obj.GetLetterGrade() << "\n";

return out;
 }

Но когда я пытаюсь использовать его в основном, я получаю сообщение об ошибке... ошибка чтения символов строки.

вот немного моего основного

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include "Project3Header.h"
using namespace std;


//Tyler Smith
void StdInfo(Student array[], int size);
Student * MakeStudentArray(int size);
int main(){

ifstream inData;
int size = 0;
int highsize = 0;
char data[65535];



inData.open("F:\\grade.dat");
if (!inData)
{
    cout << "Error opening file.\n";
    cout << "Perhaps the file is not where indicated.\n";
    return 1;
}

while (inData.getline(data, 65535)) {
    size++;

}
inData.close();
cout << size;
Student s1;
Student * ptArr;
  ptArr = MakeStudentArray(size);

  for (int i = 0; i < size; i++){
  ptArr[i]= s1;
  }

  StdInfo(ptArr,size);
   /* for (int i = 0; i < size; i++){
      cout << ptArr[i].Getlname() << ptArr[i].Getfname(); //<< ptArr[i].Get() << endl;
   }*/
    cout << ptArr[2].Getfname();
    return 0;
  }



  Student * MakeStudentArray(int size)
  {

  return new Student[size];
  }

  void StdInfo(Student array[], int size){
    ifstream in;
    in.open("F:\\grade.dat");
    string fname1,lname1="";
    int Score1, Score2, Score3, Score4, Score5=0;

    for (int i = 0; i < size; i++) {
        in >> lname1;
        in >> fname1;
        in >> Score1;
        in >> Score2;
        in >> Score3;
        in >> Score4;
        in >> Score5;
        array[i].Setlname(lname1);
        array[i].Setfname(fname1);
        array[i].SetTestScore1(Score1);
        array[i].SetTestScore2(Score2);
        array[i].SetTestScore3(Score3);
        array[i].SetTestScore4(Score4);
        array[i].SetTestScore5(Score5);
        array[i] = array[i + 1];
        //for (int j = 0; j < 5; j++) {
        //in >> array[i].testScore[j];
        //}
        }

 }

Когда я попробую, это просто не сработает. Когда я делаю это в режиме отладки, он останавливается у оператора перегрузки и остается "ошибкой чтения rhs строки",

  • 1
    Какой точный текст ошибки? На какой линии это происходит? MakeStudentArray делает правильные вещи?
  • 1
    Тип возврата оператора присваивания должен быть Student& не Student
Показать ещё 5 комментариев
Теги:
project

2 ответа

3
Лучший ответ

Суть вашей проблемы - не (нетрадиционный) оператор присваивания, а функция MakeStudentArray.

Я жестко запрограммировал размер до 10, вместо того, чтобы читать его из файла и использовать

Student * MakeStudentArray(int size)
{
    return new Student[size];
}

позаботиться о вызове delete [] ptArr; после того, как я был сделан в основном (беспокоясь об исключениях, как я сделал), и все было хорошо.

Ваша версия выделяет студентов (возможно, всю кучу), а не массив.

Если я изменю код вопроса, который вы опубликовали в

for (int i = 0; i < size; i++){
  ptArr[i].operator= (s1);
      //^------- you said 0, right?
}

то у меня проблема. Это связано с тем, что цикл for предполагает, что "массив" является смежным, но ваша функция вводила массив точек, а не массив учеников, поэтому он вступает в доброту, только знает, где, когда он пытается перебрать "массив".
Использование моей версии предложения должно решить проблему, поскольку она выделяет массив, используя new[size] а также упрощает удаление.


Изменить 1:
В остальном на main размещенном сейчас, возможно, вы продолжаете пытаться установить ptArr[0] несколько раз в цикле, но затем вызов StdInfo попытается пройти "массив" и даст вам ошибку. Если вы хотите индексировать в массив, используя [] он должен быть смежным, поэтому функция выделения, MakeStudentInfo прежнему будет причиной проблемы.


Edit2:
Теперь есть еще больше кода, посмотрите на свою функцию StdInfo. Без дополнительных деталей он делает это:

   for (int i = 0; i < size; i++) {
       //...
       array[i] = array[i + 1];
   }

Что вы пытаетесь достичь здесь? Похоже, установить текущий array[i] на то, чего мы еще не получили. Как только i доберусь до size i+1 вы покинете свой массив.
Удаление этой строки было бы хорошей идеей.

  • 0
    Хорошо, я думаю, что следую за тобой. Я внес исправления, которые вы сказали, и теперь у меня, похоже, другая проблема. Я пытаюсь запустить программу, и появляется сообщение «consoleapplication.exe перестала работать», и она пытается найти решение для Windows. Затем, когда я нажимаю на отладчик, он завершает работу со словами «Loaded 'C: \ Windows \ SysWOW64 \ msvcr120d.dll'. Не удается найти или открыть файл PDB». снова и снова. Хотя я продолжу спрашивать тебя, пока у тебя есть ухо. @doctorlove
  • 0
    Если вы убедитесь, что вы создали отладочную версию, которая может помочь. Я вижу еще одну проблему, теперь у вас есть больше кода ... редактировать 2, чтобы следовать.
Показать ещё 2 комментария
1

Оператор присваивания должен возвращать ссылку на назначенный объект, а не на копию. Также подумайте об использовании идиомы copy & swap

Student& Student::operator=(const Student &rhs){
  • 0
    Верно, но действительно ли это дает (частично) описанную ошибку, не возвращая ссылку?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню