重载运算符 =,读取字符串时出错

Overloading operator =, error in reading string

本文关键字:字符串 出错 读取 运算符 重载      更新时间:2023-10-16

我正在尝试将重载写入 = 运算符,以便它允许您直接将一个学生对象分配给另一个学生对象。因此,它将复制所有私有数据成员。这是我到目前为止所拥有的。

.h

#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

学生记忆.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 错误读取字符串字符">

问题的意义不是(非常规的(赋值运算符,而是MakeStudentArray函数。

我将大小硬编码为 10,而不是从文件中读取它,并使用

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

在我完成主要工作后,小心地打电话给delete [] ptArr;(担心异常(,一切都很好。

您的版本分配学生(可能遍布整个堆(,而不是数组。

如果我将您在 main 中发布的问题代码更改为

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

然后我遇到了一个问题。这是因为 for 循环假定"数组"是连续的,但您的函数更新了一个点数组,而不是一个学生数组,所以它只知道当它试图遍历"数组"时在哪里。
使用我的建议版本应该可以解决问题,因为它使用 new[size] 分配数组,并且更容易删除。


编辑 1:
随着其余的main现在发布,也许您确实一直在尝试在循环中多次设置ptArr[0],但是调用StdInfo将尝试遍历"数组"并会给您错误。如果您希望索引到数组中,使用 []必须是连续的,因此分配函数MakeStudentInfo仍然是问题的原因。


编辑2:
现在有更多的代码,看看你的StdInfo函数。如果没有额外的细节,它会这样做:

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

你想在这里实现什么?看起来将当前array[i]设置为我们尚未达到的内容。一旦i到达size i+1将关闭阵列的末尾。
删除该行将是一个好主意。

值运算符应返回对已分配对象的引用,而不是副本。还要考虑使用复制和交换习惯用法

Student& Student::operator=(const Student &rhs){