getline() glitch

in my sms(student management system)
when i use the getline() to take full name and store in to a vector the program "glitches" i really don't know how to describe it; but i don't get the chance to enter the first person's name. the program goes straight and ask for the second person's name supposed if there are more than one person's name to be recorded;
aside that everything work normally;
when i go to view the data, the first person's name is set blank but all others work perfectly;
here is my code and how do i fix this "gliche";
please first run the program to know what i am try to describe
the problem is in CREATING A NEW CLASS
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
  #include<iostream>
#include<iomanip>
#include<vector>

using namespace std;
int num;
	vector<string> names;
	vector<string> id;
	vector<string> marks;
	string input;
	string newmember;

int main(){
	int choice;
	bool again=true;
	do{	
	system("cls");
	cout<<setw(90)<<"***********************************************************************************************************************\n";
	cout<<setw(70)<<"STUDENT MANAGEMENT SYSTEM\n";
	cout<<setw(90)<<"***********************************************************************************************************************\n\n";
	cout<<"ENTER A NUMBER THAT CORRESPOND TO ONE OF THE OPERATIONS BELOW: \n";
	cout<<setw(90)<<"----------------------------------------------------------------------------------------------------------------------\n";
cout<<"1 CREATE NEW CLASS\n";
cout<<"2 VIEW CLASS\n";
cout<<"3 ADD NEW STUDENT\n";
cout<<"4 EDIT STUDENT DETAILS\n";
cout<<"5 REMOVE STUDENT\n";
cout<<"6 EXIT PROGRAM\n";
	cin>>choice;
	
	switch(choice){
//CREATING THE NEW CLASS
		case 1:
			system("cls");
 	cout<<"ENTER NUMBER OF STUDENT IN CLASS: ";
	cin>>num;
	names.resize(num);
	
	for(int j=0; j<names.size(); j++){
		int a=j+1;
		cout<<"Enter student "<<a<<" name: ";
		getline(cin,names[j]);
	}
	break;
	
		case 2:
			system("cls");
			
	for(int i=0; i<names.size(); i++){
		
		cout<<names[i]<<endl;
			}
		cout<<"press the enter key to exit this window";
		cin.get();
		cin.ignore();
	break;
	
	case 3:
		system("cls");
		do{
		cout<<"ENTER STUDENT NAME: ";
		cin>>newmember;
		names.push_back(newmember);
		cout<<"do you want to add another member?: Y: YES OR N: NO ";
		cin>>input;
	}while(input=="yes"||input=="YES"||input=="y"||input=="Y");
	break;
	case 4:
		system("cls");
		cout<<"ENTER STUDENT NAME OR ID TO EDIT\n";
		cin>>input;
		for(unsigned i=0; i<names.size();i++){
			if(names.at(i)==input){
				names.erase(names.begin()+i);
				cout<<"ENTER NEW STUDENT NAME: ";
				cin>>newmember;
				names.push_back(newmember);
			break;
			}else{
				cout<<"NO MATCH FOUND FOR NAME OR ID. PLEASE ENTER PRE-EXISTING NAME OR ID TO EDIT";
			}
		}
			
		
		break;
	case 5:
		system("cls");
		cout<<"ENTER STUDENT NAME OR ID TO DELETE\n";
		cin>>input;
		for(unsigned i=0; i<names.size();i++){
			if(names.at(i)==input){
				names.erase(names.begin()+i);
			}
		}
		case 6:
			system("cls");
		cout<<"GOOD BYE";
		again=false;
			break;
}
	
	}
	while(again);
}
Last edited on
when you choose 1
then set the class size
then there is that glitch;
but when i use cin to take the name everything works fine except i cannot take full name

the getline() works okay but the very first person's name cannot be entered
help me solve this bug
Last edited on
Without even looking at your code I can guess that you are leaving the newline in the input buffer after reading the number. The getline reads up to the next newline, so it is basically reading nothing.

One way to solve this is to call cin.ignore(99999, '\n') to extract the newline after you read the number. The first parameter should be large in case there is some extra space. The perfect value is numeric_limits<streamsize>::max(), which is interpreted as "infinity".

Another way to fix it is to always read in complete lines. So to read a number you would do this:

1
2
3
4
5
string line;
getline(cin, line); // read a complete line, which includes extracting the newline
istringstream iss(line);
int n;
iss >> n;

EDIT: I should have mentioned that you need to include <limits> for numeric_limits and/or <sstream> for istringstream.
Last edited on
@dutch
i am absolute new to programming all that you've said make a little sense to me but how do i implement it?
where do i call the cin.ignore(99999,'\n') and if i want to use the perfect value, do i pass it as a parameter to the cin.ignore(); or would simply write that line in my codes after including the <limits>.

i am absolute beginner
please help me with the implementation and also clarify this for me
the second method: is it equivalent to conversion string into other types?
example
1
2
3
4
string input;
int number;
getline(cin,input);
stringstream(input)>>num;
Last edited on
Hello rapanomalous,

I will try this in another way. What is happening is that std::cin >> someVariable; will extract from the input buffer up to, but not including a white space or new line whichever comes first and leave anything left in the input buffer. The other case is std::getline(std::cin, aString); will extract from the input buffer up to and including the new line then it through away the new line. And if "getline" has a third parameter for a delimiter it will extract from the input buffer, (or file), up to and including the delimiter then discard the delimiter leaving the pointer at the next character following the delimiter.

Using all std::cin >> someVariable; or all std::getline(std::cin, aString); is not a problem. Only when you mix the two does it cause a problem.

What dutch is saying is that after using the "cin" and before a "getline" you need to clear the input buffer. It would look something like this:
1
2
3
4
5
6
std::cin >> someVariable;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.

// <--- Other code.

std::getline(std::cin, aString);

It is best to follow the "cin" with the "cin.ignore", but you can use it before a "getline" statement.

Hope that helps,

Andy
yeah that really helped;
thank you Dutch
thank you Andy
i am much grateful
Topic archived. No new replies allowed.