Need help with cin.clear and cin.ignore

This is what we were asked to:

Write a program which asks you to enter a name in the form of first middle initial last. So you might enter for example samuel p. clemens. Use getline to read in the string because it contains spaces. Also, apparently the shift key on your keyboard doesn’t work, because you enter it all lower case. Pass the string to a function which uses .find to locate the letters which need to be upper case and use toupper to convert those characters to uppercase. The revised string should then be returned to main in the form Last, First MI where it will be displayed.

The code works but I have to press enter twice after inputting a name. It has something to do with the cin.ignore and cin.clear. Is their way to avoid having to press enter twice? Any help would be great.

Here is my code:

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
#include <iostream>
#include <string>
#include <cctype>
using namespace std;

//function prototype
void capitalize(string name, string &first, string &mi, string &last);


int main()
{
	
	char run;
	string name, first, mi, last;

	do
	{

		cout << "Enter a name. FIRST MI. LAST" << endl;
		getline(cin, name);
		cin.clear();
		cin.ignore(80, '\n');

		capitalize(name, first, mi, last);

		cout << "You entered: " << name << endl;
		cout << "It was converted to: " << last << ", " << first << " " << mi << endl;


		cout << "Do you have another name to enter? Y/N" << endl;
		cin >> run;

		while (toupper(run) != 'Y' && toupper(run) != 'N')
		{
			cout << "Entry invalid. Do you have another name to enter?  Y for yes or N for no." << endl;
			cin >> run;
		}

	} while (toupper(run) == 'Y');

	return 0;
}

//function
void capitalize(string name, string &first, string &mi, string &last)
{

	int num, count;
	char letter;
	for (count = 1; count < 4; count++)
	{
		num = name.find(" ", 0);
		if (count == 1)
		{
			first = name.substr(0, num);
		}
		else if (count == 2)
		{
			mi = name.substr(0, num);
		}
		else if (count == 3)
		{
			last = name.substr(0, num);
		}
		else
		{
			cout << "Error" << endl;
		}

		name.erase(0, num + 1);
	}

	first[0] = toupper(first[0]);
	mi[0] = toupper(mi[0]);
	last[0] = toupper(last[0]);

}
Last edited on
After getline you should not use cin.ignore().
1
2
3
getline(cin, name);
cin.clear();
cin.ignore(80, '\n');


Should be :
getline(cin, name);
that fixes it so I dont have o press enter twice but now if I run through the program a second time it just skips the place where I enter another name.
cin >> run;

Should be :
cin >> run; cin.ignore();

That is how you use cin.ignore().
Last edited on
That works better. Thank you!
You could also think along the following lines, it doesn't need cin.ignore() or the use of arrays. There are comments throughout the program, read + research and if anything is still unclear come back here:
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
#include<iostream>
#include<locale>//for toupper( , locale());
#include<sstream>//for stringstream;
using namespace std;

int main(){

   cout<<"Enter the full name (first, middle, last): \n";
   string name;
   getline(cin, name);
   stringstream stream(name); //initializes stringstream object, stream, with string, line; read up sstream in unfamiliar;
   string first_name, mid_name, last_name;
   stream>>first_name>>mid_name>>last_name;//stream is read into three further strings

    first_name = toupper(first_name[0], locale()) + first_name.substr(1);//this version of toupper() has 2 arguments and returns the
   // uppercase of the character unlike the toupper() with 1 argument that returns int and has to be implicitly cast to char,
   //requires locale header file;
   if(mid_name.length()>1){
       mid_name = toupper(mid_name[0], locale()) + mid_name.substr(1);
       }
    if(mid_name.length() == 1){//as in the samuel p. clements example, you don't want to be picking up random stuff from memory,
            //can do similar for first_name and last_name too if you wish;
            mid_name = toupper(mid_name[0]);
       }
    last_name = toupper(last_name[0], locale()) + last_name.substr(1);
    cout<<"The full name converted is: \n";
    cout<<first_name<<" "<<mid_name<<" "<<last_name;
}

In your initial menu you can also have an option in case a person doesn't use a middle name and for anything else you can think of

Topic archived. No new replies allowed.