这只是跟my last question一起,有人让我上传文件,所以我会删除所有无用的功能,并且主要代码特别是与输出有关,这是我的第3个关于堆栈溢出的问题所以我仍然不知道它是如何工作的,如果你想回答,请查看my last (2nd) question了解详情。这是代码:
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
const int MAX_SIZE = 1000;
struct Student
{
string studentID;
string firstName;
char midInitial;
string lastName;
};
void menu()
{
cout<<" CLASS ROSTER APPLICATION"<<endl;
cout<<"========================================="<<endl;
cout<<"ADD a student record..................[A]"<<endl;
cout<<"DELETE a student......................[D]"<<endl;
cout<<"EDIT a student record.................[E]"<<endl;
cout<<"INQUIRY about a student...............[I]"<<endl;
cout<<"LIST all students.....................[L]"<<endl;
cout<<"QUIT the system.......................[Q]"<<endl;
}
int linearSearch(const Student roster[], int numStuds, string sID)
{
int i;
for (i=0; i<numStuds; i++)
{
if (roster[i].studentID == sID)
return i;
}
return -1;
}
void selSort(Student roster[], int numStuds)
{
int minIDPos;
Student tempStudRecord;
int i,j;
for (i=0; i<numStuds-1; i++)
{
minIDPos = i;
for (j=i+1; j<numStuds; j++)
{
if (roster[j].studentID < roster[minIDPos].studentID)
minIDPos = j;
}
tempStudRecord = roster[i];
roster[i] = roster[minIDPos];
roster[minIDPos] = tempStudRecord;
}
}
void listStudents(const Student roster[], int numStuds)
{
cout<<"C L A S S R O S T E R"<<endl;
cout<<"Student ID # First Name M.I. Last Name"<<endl;
cout<<"---------------------------------------------"<<endl;
int i2=0; //just a counter.
while (i2<numStuds)
{
cout<<left;
cout<<setw(14)<<roster[i2].studentID<<setw(13)<<roster[i2].firstName;
cout<<roster[i2].midInitial<<". "<<roster[i2].lastName;
cout<<endl;
i2++;
}
cout<<right;
cout<<"---------------------------------------------"<<endl;
cout<<"Enrollment: "<<i2<<endl;
}
int main()
{
Student roster[MAX_SIZE];
fstream inFile;
fstream outFile;
string filename, sID;
Student newStudent;
int numStuds = 0;
char choice;
int i;
cout<<"Enter the name of the data file> ";
cin>>filename;
/** 7. open the data file for input **/
inFile.open(filename.c_str(), ios::in);
if (inFile)
{
/** 8. write a while loop to read the data from the file
into the roster array; the numStuds (number of Students)
must be updated as the records are read from the file.
Also, close the file after its contents are read into the
roster array.
**/
while (!inFile.eof() && numStuds < MAX_SIZE)
{
inFile>>roster[numStuds].studentID>>roster[numStuds].firstName;
inFile>>roster[numStuds].midInitial>>roster[numStuds].lastName;
numStuds++;
}
inFile.close();
}
do
{
cout<<endl;
menu();
cout<<endl;
cout<<"Select an option-> ";
cin>>choice;
cout<<endl;
switch(toupper(choice))
{
case 'A': cout<<"Enter the student ID #> ";
cin>>newStudent.studentID;
cout<<"Enter the student's first name> ";
cin>>newStudent.firstName;
cout<<"Enter the student's middle initial> ";
cin>>newStudent.midInitial;
cout<<"Enter the student's last name> ";
cin>>newStudent.lastName;
addStudent(roster,numStuds,newStudent);
break;
case 'D': /** 9. write code here to remove a student from the roster **/
cout<<"Enter the student ID Number: ";
cin>>sID;
deleteStudent(roster, numStuds, sID);
break;
case 'E': /** 10. write code to edit the record for a student with a specified ID # **/
cout<<"Enter the student ID Number: ";
cin>>sID;
editStudent(roster, numStuds, sID);
break;
case 'I': /** 11. write code to perform an inquiry (obtain full name) on a student with
with a specified ID # **/
cout<<"Enter the student ID Number: ";
cin>>sID;
studentInquiry(roster, numStuds, sID);
break;
case 'L': /** 12. write code to sort and then generate class roster **/
selSort(roster, numStuds);
listStudents(roster, numStuds);
break;
case 'Q': break;
default: cout<<"Invalid menu choice...try again!"<<endl;
}
}while(toupper(choice) != 'Q');
/** 13. open the data file in output mode and error-check to ensure
that it was successfully opened.
**/
outFile.open(filename.c_str(), ios::out);
if (!outFile)
{
cout<<"Unable to open "<<filename<<" for output. "<<endl;
return -1;
}
/** 14. overwrite the data file in the order:
student ID, firstname, middle initial and last name, one record per line.
make sure that you have spaces between the fields.
**/
for (i=0;i<numStuds;i++)
{
outFile<<roster[i].studentID<<" "<<roster[i].firstName<<" ";
outFile<<roster[i].midInitial<<" "<<roster[i].lastName<<endl;
}
/** 15. close the output file **/
outFile.close();
return 0;
}
答案 0 :(得分:2)
这里
while (!inFile.eof() && numStuds < MAX_SIZE) {
inFile >> roster[numStuds].studentID >> roster[numStuds].firstName;
inFile >> roster[numStuds].midInitial >> roster[numStuds].lastName;
numStuds++;
}
将numStuds
的值保持高于应有的值,因为inFile.eof()
只会在文件结束后返回true
,直到您实际上已经尝试阅读文件的末尾。
修复它的一种方法是将其更改为
while (numStuds < MAX_SIZE &&
(inFile >> roster[numStuds].studentID >> roster[numStuds].firstName >>
roster[numStuds].midInitial >> roster[numStuds].lastName)
) {
numStuds++;
}
虽然你最好定义一个为你读取结构的函数
std::istream& operator>>(std::istream& stream, Student& student)
{
stream >> student.studentID >> student.firstName
>> student.midInitial >> student.lastName;
return stream;
}
其工作原理如下:
while (inFile >> roster[numStuds]) {
numStuds++;
}
正如@JoachimPileborg所建议的,以下情况会更好(一旦为你的结构定义operator>>
):
std::vector<Student> roster;
//...
std::copy(
std::istream_iterator<Student>(inFile),
std::istream_iterator<Student>(),
std::back_inserter(roster)
);