String Functions: Finding where this character goes

Hello
I am trying to create a program which will read in from a file and output to the users display. The input will consist of three uppercase letters followed by last_name, first_name middle_initial. The first character 'M' or 'F' indicates gender of the person. The second character is 'M', 'S', 'W', or 'D' indicating if the person is married, single, widowed, or divorced respectively. The third character will either be 'D' or 'N' indicating whether or not the person has a doctorate. There will be no errors in the first three characters of input.
The last name will always end with a comma, however the last name may be more than one word. The first name may also be more than one word. The middle initial will always follow a period, however, some people don't have a middle initial.

edit: I forgot to mention there can be any amount of spaces between each part of the name. I'm not sure why, but the input file is not currently displaying the correct amount of spaces between each name. I have edited the first few names to show you an example. The rest of the input is similar. I have have used[] to indicate a space
***I am only allowed to use the following string functions: find, substr, size
***I cannot use string.erase

My example input from INPUT.txt:
FMN [][][][]Bach[][][][][][]Dietz,[][]Johanna[][][][][][][]Good
MSD [][][][][][][]Curie,[][][][]Marty
FWN [][][] Parker,[]Alice[][][]Mary[][][][]M.
FMN Bach, Johanna M.
MSD Curie, Marty A.
FWN Parker, Alice M.
FDN Bach, Johanna
MSD Curie, Marty A.
FWN Parker, Alice M.
FDN Bach, Johanna S.
MSD Curie, Marty A.
FWN Parker, Alice
FDN Bach, Johanna S.
MSD Curie Hegde, Marty Martian
FWN Parker, Alice M.
FDN Bach, Johanna S.
MSD Curie, Marty A.
FDN Parker, Alice M.

My current 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
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
132
133
134
135
136
137
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>

using namespace std;

enum marital_status { MARRIED, SINGLE, WIDOWED, DIVORCED };
marital_status ms_out( char ch1 );
void count_ms( marital_status ms, int& m, int& s, int& w, int& d );

int main()
{
	ifstream infile;
	infile.open("INPUT.txt");

	char gender_char, ms_char, doctorate_char;
	int x=0, y=0, z=0;		int num_of_doctorate=0; //Initializing ints
	int num_of_married=0;	int num_of_single=0;	//Counting ints must be assigned
	int num_of_widowed=0;	int num_of_divorced=0;	//a value of 0 to work properly

	string name, first, middle, last, temp;
	marital_status void_ms;

	gender_char = infile.get();
	ms_char = infile.get();
	doctorate_char = infile.get();

	while( !infile.eof() )
	{
//The following two function calls evaluate and record the marital status
	void_ms = ms_out( ms_char );
	count_ms( void_ms, num_of_married, num_of_single, num_of_widowed, num_of_divorced );

	if ( doctorate_char == 'D' )
	{	cout << "Dr. ";	
		num_of_doctorate++;	}	//Adds 1 to total doctorate count
	else if ( gender_char =='M' )
		cout << "Mr. ";
	else if ( ms_char =='M' )
		cout << "Mrs. ";
	else
		cout <<"Ms. ";

	getline( infile, name); // Get's Last name, first name, middle initial (if any)
	while( name[z] ==' ' )  //Looks for spaces before the beginning of last name
		z++;				//Saves location of the beginning of last name

	while( name[x] != ',' ) //While loop searches for comma (indicator of the end of last name)
		x++;                //Assigns location of the end of last name char

	last = name.substr(z,x-z);//Stores the last name as a string

	y = x+1;                //Assigns location of the char after the comma to y
	while( name[y] == ' ' ) //While loop searches for beginning of first name location
		y++;				//Assigns location of the beginning of first name char
	first = name.substr(y); //Assigns first name and middle initial if applicable

	x = last.find(' ',0);	//Finds if last name is more than one word
	z=x;
	if ( x != -1 )			//If last name is more than one word
	{	while( last[x] == ' ' ) //While loop searches for spaces
		{x++;	y++;}			//Assigns amount of spaces
		temp = last.substr(0,z);//Puts first last name in temp
		temp +=" ";				//Formatting space
		temp += last.substr(x,y+1);	//Adds the last name to temp
		last = temp;			//Assigns the correctly formatted last name
	}

	x = first.find('.', 0);	//While loop searches for middle initial
	if ( x != -1 )			//If middle initial applicable...
	{	middle = first.substr(first.size()-3);	//Assigns middle initial
		first = first.substr(0, first.size()-3);	//Assigns first name without the middle
	}

	y = first.find(' ',0);	//Looking for excess spaces
	if ( y != -1 )	//IF*1*		//If there are any extra spaces
	{
		temp = first.substr(0,y);	//Stores first name with no extra spaces at the end
		x = first.size()-1;
		if ( x-y > 1 )	//IF*2*	//If there are any characters left after the extra spaces
		{					//That means a second first name must exist
			while( first[y] == ' ' && y < x )	//Looking for extra spaces
				y++;							//Counting how many spaces
			z=y;		//Stores location of last excess space before the second first name
			while( first[y] !=' ' && y < x )	//Looking for valid chars
				y++;							//Counting valid chars
			if( z < y )	//IF*3*						//If there are more than one last name
			{	temp +=" ";							//Formatting space
				temp += first.substr(z,y-z);		//Combining first and second name
			}			//End IF*3*
		}		//End IF*2*
		first = temp;
	}		//End IF*1*
	if ( middle.size() > 1 ) //If there was a middle name, add it to first
	first += middle;

	cout << first << " " << last;			 //Displays name
	cout << '\n';
	
	gender_char = infile.get();		//Assigns next gender char
	ms_char = infile.get();			//Assigns next marital status char
	doctorate_char = infile.get();	//Assigns next doctorate char
	x=0; y=0; z=0; middle="";		//Re initializing to zero/empty

	}	//END OF WHILE LOOP
	cout << "Number of people with doctorates: " << num_of_doctorate << endl;
	cout << "Number of people who are married: " <<	num_of_married << endl;
	cout << "Number of people who are single: " << num_of_single << endl;
	cout << "Number of people who are widowed: " <<	num_of_widowed << endl;
	cout << "Number of people who are divorced: " << num_of_divorced << endl;
	
	system ("PAUSE");
	return 0;
}
marital_status ms_out ( char ch1 )
{
	switch ( ch1 )
	{
	case 'M': return MARRIED; break;
	case 'S': return SINGLE; break;
	case 'W': return WIDOWED; break;
	default: return DIVORCED; break;
	}	//Default assumes char == D
}
void count_ms( marital_status ms, int& m, int& s, int& w, int& d )
{
	switch ( ms )
	{
	case MARRIED:	m++; break;
	case SINGLE:	s++; break;
	case WIDOWED:	w++; break;
	case DIVORCED:	d++; break;
		default: cout << "Something is wrong!!!!";
	}
}	


My current output:
Mrs. Johanna Goo Bach Dietz
Dr. Marty Curie
Ms. Alice Mary M. Parker
Mrs. Johanna M. Bach
Dr. Marty A. Curie
Ms. Alice M. Parker
Ms. Johanna Bach
Dr. Marty A. Curie
Ms. Alice M. Parker
Ms. Johanna S. Bach
Dr. Marty A. Curie
Ms. Alice Parker
Ms. Johanna S. Bach
Dr. Marty Martia Curie Hegde
Ms. Alice M. Parker
Ms. Johanna S. Bach
Dr. Marty A. Curie
Ms. Alice M. Parker
Number of people with doctorates: 6
Number of people who are married: 2
Number of people who are single: 6
Number of people who are widowed: 5
Number of people who are divorced: 5
Press any key to continue . . .

If you notice person 1 and person 14 both have two first names and no middle initial. Their second first name is cut off by one character. I cannot find the error anywhere. Any help would be greatly appreciated.

Thank You
Last edited on
FWN Parker, Alice Mary M.

I recommend you use the extraction operator>> to extract the first three characters to a string, then use getline() to retrieve the last name, using the optional third parameter, the ',' in this case, then another getline() to retrieve the rest of the name. It really doesn't look like you actually need to store the first and middle name just use one string for both first and middle.

1
2
3
4
5
6
string status; // A string to hold the first three characters.
string last_name;
string first_name;
file >> status;
getline(file, last_name, ','); // Get the last name stop at the comma, throw away the comma.
getline(file, first_name); // Get the first and middle name. 


Then test each character in the status string to build your title. Then append the frist_name, then the last name.
Thank you for your response. I hadn't thought of storing the first 3 chars as a string, or capturing the last name immediately as described. I will look into this today.

I did edit my original post, I had forgot to mention the amount of spaces between each name. For whatever reason the forum is automatically removing the excess spaces from my "input". Perhaps now it is clearer why I had so many tests.

Last edited on
First don't edit your posts to change the content, add a new post, that makes following the conservation difficult.

I had forgot to mention the amount of spaces between each name.

I would write a function to remove this excess white space after you retrieve the names but before you actually go to use the information.
Last edited on
Topic archived. No new replies allowed.