Problem with istream operator

Ok. This isnt the first time ive run into problems with classes ive made before.
I have created a school class. Here is the header file.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#ifndef SCHOOL_H
#define SCHOOL_H

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

class School
{
public:


	School();
	School(string name, int record_number);
	School(string name, int num_students, int num_teachers, int record_number);

	string get_name()const;
	int get_num_students()const;
	int get_num_teachers()const;
	int get_record_number()const;

	void set_name(string name);
	void set_num_students(int num_students);
	void set_num_teachers(int num_teachers);
	void set_record_number(int record_number);
	bool write_record(fstream& os);
	bool read_record(fstream& is);


	friend ostream& operator << (ostream& os, const School& aSchool);
	friend istream& operator >> (istream& is, School& aSchool);

private:
	char m_name[25];
	int m_num_students, m_num_teachers, m_record_number;

};
#endif




ok so my problem is when I call this code in my main.

School temp;

cin >> temp;

when this code is called, it skips passed the part, where I should be able to enter the school name and automatically goes to the next part of the istream that asks for the number of students.
Below is the code for my istream

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
istream& operator >> (istream& is, School& aSchool)
{
	string name;
	int students, teachers, record_number;

	if(is == cin)
		cout << "Enter name of school: ";
	mygetline(is, name); 
	if(is.eof() == true)
		return is;
	if(is == cin)
		cout << "Enter number of students: ";
	is >> students;
	if(is == cin)
		cout << "Enter number of teachers: ";
	is >> teachers;
	if(is == cin)
		cout << "Enter record number: ";
	is >> record_number;

	aSchool.set_name(name);
	aSchool.set_num_students(students);
	aSchool.set_num_teachers(teachers);
	aSchool.set_record_number(record_number);

	return is;
}


here is the code for mygetline that I am using. This code gets a whole line and stores that into a string. It works properly. Ive used just the plain getline function as well and got the same reaction.

1
2
3
4
5
6
7
8
9
10
void mygetline(istream& is, string &str)
{
    str = "";                                            // remove old contents
    if (is != cin && is.peek() == '\n')      // skip to next line if needed
        is.get(); 

    char ch;
    while((ch=is.get()) != '\n' && ch != EOF)    // keep reading chars until
        str += ch;                                                // end of line or file reached
}


so just to sum up I am going to show the output of the program and point out the issue at hand.


Welcome to the Schools data base

This is the size of School = 40

        A:      Add/Replace new School to file
        R:      Read School from file
        P:      Print all Schools from file
        N:      Create new data file
        X:      Exit program
Select choice:a
Create new School
Enter name of school: Enter number of students: 35 //skipped the name entering 
Enter number of teachers: 23
Enter record number: 1
School name:   // i never got to enter the name
# of students: 35
# of teachers: 23
Record # : 1

        A:      Add/Replace new School to file
        R:      Read School from file
        P:      Print all Schools from file
        N:      Create new data file
        X:      Exit program
Select choice:




I hope I have explained my problem clearly. I ran into this same issue with my previous classes using both getline and mygetline(my teacher made this)

Any help would be great.... But I would love to have an explanation as to why this is happening


Thanks,
Brandon
Any response would be greatly appreciated

Thanks
You have a trailing newline in the input buffer. Either get rid of all uses of >> to get input, or use cin.ignore(MAX_INT,'\n'); just before calling getline().
I recommend the first option.
what do you mean, when you say remove all instances of >>. to remove them in my main?? or in my istream definition. I tried the second option before i called getline, and i got an error saying mAX_INT was undefined
what do you mean, when you say remove all instances of >>.
I mean >> should not be used anywhere in the program.

MAX_INT is defined in <climits>.
yea thats the thing. My instructor actually created the main portion of the program. He told us to make the school class for homework and to include the >> and << operators accessors and mutators for the school class, and also to make a write and read method because we are going to use the class with a random access file. Here is his main, which uses cin.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include "School.h"

using namespace std;

void menu();

void main()
{
	// Welcome message
	cout << endl << "Welcome to the Schools data base" << endl << endl;

	// Open file for input AND output
	fstream data_file("Schools.dat", ios::out | ios::in );

	// Problem: If file does not exist, an error occurs
	// Solution: Create an empty file
	if (!data_file.is_open()) {
		cout << "Creating new School data file" << endl;
		ofstream temp_file("Schools.dat");
		temp_file.close();
		data_file.open("Schools.dat", ios::out | ios::in );
						
		// Write 100 empty records to create new file
		cout << "Creating 100 empty records in the new data file: Schools.dat" << endl;
		School empty_School;
		for (int i = 0; i < 100; i++) {
			empty_School.set_record_number(i);
			empty_School.write_record(data_file);
		}

	}
	
	cout << "This is the size of School = " << sizeof(School) << endl;

	// Check to make sure both files were opened
	if (!data_file.is_open()) {
		cerr << "Error opening file: Schools.dat" << endl;
	} else {
		char ch = 'a';
		School empty_School, temp;
		int id, i;

		menu();
		cin >> ch;

		while (ch != 'X' && ch != 'x') {
			switch(ch) {
				case 'n':		// Write 100 empty records to create new file
				case 'N': cout << "Creating new data file: Schools.dat" << endl;
					for (i = 0; i < 100; i++) {
						empty_School.set_record_number(i);
						empty_School.write_record(data_file);
					}
					break;
				case 'a':	
				case 'A': cout << "Create new School" << endl;
					cin >> temp;
					cout << temp;
					if (temp.get_record_number() < 100)
						temp.write_record(data_file);
					else
						cout << endl << "Error: Database stores only Schools with record numbers less than 100\a" << endl;
					break;
				case 'r':
				case 'R':		// read School record from file using id to position
					cout << "Please enter School's record number:";
					cin >> id;
					temp.set_record_number(id);
					temp.read_record(data_file);
					if (id != temp.get_record_number())
						cout << "Error: Id does not match requested id:" << id << endl;
					cout << temp << endl;
					break;
				case 'x': ch = 'X';			// Quit
				case 'X': cout << "bye" << endl;
					break;
				case 'P':					// Print all Schools
				case 'p':
					cout << endl;
					cout << left << setw(10) << "Record #" << setw(18) << "School name" 
						<< setw(15) << "Quantity" << setw(10) << "Cost" << endl;
					cout << "---------------------------------------------------" << endl;
					for (i = 0; i < 100; i++) {
						temp.set_record_number(i);
						temp.read_record(data_file);
						if (temp.get_name() != empty_School.get_name())
							cout << temp << endl;
					}
					// Ran past end of file, must reset flag
					data_file.clear();
					break;

				default: cout << "Unknown command" << endl;
			}// switch

			menu();
			cin >> ch;
		} //while
	} // else

	// Close the files
	data_file.close();
}


void menu()
{
	cout << endl;
	cout << "\tA:	Add/Replace new School to file" << endl;
	cout << "\tR:	Read School from file" << endl;
	cout << "\tP:	Print all Schools from file" << endl;
	cout << "\tN:	Create new data file\a" << endl;
	cout << "\tX:	Exit program" << endl;
	cout << "Select choice:";
}


here is my school.cpp file if you were interested
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <iostream>
#include <fstream>
#include <string>
#include "School.h"
void mygetline(istream& is, string &str);

using namespace std;
School::School()
{
	set_name("Blank");
	m_num_students = 0;
	m_num_teachers = 0;
	m_record_number = 0;
}
School::School(string name, int record_number)
{
	set_name(name);
	m_num_students = 0;
	m_num_teachers = 0;
	set_record_number(record_number);
}
School::School(string name, int num_students, int num_teachers, int record_number)
{
	set_name(name);
	set_num_students(num_students);
	set_num_teachers(num_teachers);
	set_record_number(record_number);
}
string School::get_name() const
{
	return m_name;
}
int School::get_num_students() const
{
	return m_num_students;
}
int School::get_num_teachers() const
{
	return m_num_teachers;
}
int School::get_record_number() const
{
	return m_record_number;
}
void School::set_name(string name)
{
	unsigned int len = name.length();
	if(len > 25)
		len = 25;
	name.copy(m_name,len);
	m_name[len] = '\0';
}
void School::set_num_students(int num_students)
{
	if(num_students >= 0)
		m_num_students = num_students;
	else
		cout << "Error, students can not be negative." << endl;
}
void School::set_num_teachers(int num_teachers)
{
	if(num_teachers >= 0)
		m_num_teachers = num_teachers;
	else
		cout << "Error, teachers can not be negative." << endl;
}
void School::set_record_number(int record_number)
{
	if(record_number >= 0)
		m_record_number = record_number;
	else
		cout << "Error, record number has to be 0 or greater." << endl;
}
bool School::write_record(fstream& os)
{
	os.seekg(m_record_number * sizeof(School));
	os.write(reinterpret_cast<char*>(this), sizeof(School));
	return true;
}
bool School::read_record(fstream& is)
{
	is.seekg(m_record_number * sizeof(School));
	is.read(reinterpret_cast<char*>(this), sizeof(School));
	return true;
}
ostream& operator << (ostream& os, const School& aSchool)
{
	os << "School name: " << aSchool.get_name() << endl;
	os << "# of students: " << aSchool.get_num_students() << endl;
	os << "# of teachers: " << aSchool.get_num_teachers() << endl;
	os << "Record # : " << aSchool.get_record_number() << endl;
	
	return os;
}
istream& operator >> (istream& is, School& aSchool)
{
	string name;
	int students, teachers, record_number;

	if(is == cin)
		cout << "Enter name of school: ";
	mygetline(is, name);
	if(is.eof() == true)
		return is;
	if(is == cin)
		cout << "Enter number of students: ";
	is >> students;
	if(is == cin)
		cout << "Enter number of teachers: ";
	is >> teachers;
	if(is == cin)
		cout << "Enter record number: ";
	is >> record_number;

	aSchool.set_name(name);
	aSchool.set_num_students(students);
	aSchool.set_num_teachers(teachers);
	aSchool.set_record_number(record_number);

	return is;
}
void mygetline(istream& is, string &str)
{
    str = "";                                            // remove old contents
    if (is != cin && is.peek() == '\n')      // skip to next line if needed
        is.get(); 

    char ch;
    while((ch=is.get()) != '\n' && ch != EOF)    // keep reading chars until
        str += ch;                                                // end of line or file reached
}
void main()? :|
whats wrong with void main... whats the difference between that an int main

o btw.. Thanks a lot helios for your help. I got it working perfectly. I couldnt seem to use the MAX_INT though even when i included climits so i just changed the number to 256 and it worked
Last edited on
void main() isn't part of the C++ standard. int main() is so that it returns an int.

Here's a link for some reading... http://www.gidnetwork.com/b-66.html
thanks for the link.
Topic archived. No new replies allowed.