Trouble with strings

My program reads a person's name. It assigns the first name to the string first, the last name to the string last, and, if there is a middle name, assigns that to the string middle.

In the end the program is supposed to output the name in the format:
last, first middle(only the initial followed by a period).
User, Mary A.
If there is no middle name then the name is output in the format:
last, first
User, Mary

My function count_words works fine, but the function assign_names has a bug. I just started working with strings.
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
#include <iostream>
#include <string>
#include <cctype>
using namespace std;

int count_words(const string& s);
void assign_names(const string& name, int words, string& first, string& middle, string& last);

int main()
{
	string name, first, middle, last;
	int words;

	cout << "Enter your name: ";
	getline(cin, name);
	words = count_words(name);
	assign_names(name, words, first, middle, last);
	cout << "First = " << first << endl
		<< "Middle = " << middle << endl
		<< "Last = " << last << endl;
	system("pause");
	return 0;
}
int count_words(const string& s)
{
	int word_count = 0;
	char current, last;
	last = s[0];
	current = s[1];
	int index = 1;

	if (!isspace(last))
		word_count++;
	while (index < s.length())
	{
		if ((!isspace(current)) && (isspace(last)))
			word_count++;
		last = current;
		index++;
		current = s[index];
	}
	return word_count;
}
void assign_names(const string& name, int words, string& first, string& middle, string& last)
{
	int name_index = 0, first_index = 0, middle_index = 0, last_index = 0;

	if (words == 2)
	{
		do
		{
			first[first_index] = name[name_index];
			first_index++;
			name_index++;
		} while (name[name_index] != ' ');
		name_index++;

		do
		{
			last[last_index] = name[name_index];
			last_index++;
			name_index++;
		} while (name_index < name.length());
	}
	else if (words == 3)
	{
		do
		{
			first[first_index] = name[name_index];
			first_index++;
			name_index++;
		} while (name[name_index] != ' ');
		name_index++;

		do
		{
			middle[middle_index] = name[name_index];
			middle_index++;
			name_index++;
		} while (name[name_index] != ' ');
		name_index++;

		do
		{
			last[last_index] = name[name_index];
			last_index++;
			name_index++;
		} while (name_index < name.length());
	}
}
Last edited on
What is your output? What is your input?
If I input a two part name like, Mary User, or a three part name like, Mary Annabelle User, I get an error message:

Debug Assertion Failed! Expression: string subscript out of range.

If I input a name with less than two or more than three parts I just get the output:


First = 
Middle = 
Last = 
Hi,

Consider storing an individual person's names in a std::vector, that way you can accommodate multiple middle names, and accessing middle initials is easy.

For an input string that is all the names together, use the find algorithm to search for the position of a space, so that string can be easily split into individual names.

http://www.cplusplus.com/reference/string/basic_string/find/

Or use a for loop to go through the whole string and push_back the positions of the spaces into another vector. Use them to make words to put in the names vector.

If that isn't allowable, then there are these observations:

If I input a name with less than two or more than three parts I just get the output:


That happens because the assign_names function only deals with 2 or 3 names, not 1 or 4 or anything else.


You have code repetition for the first and last names, consider making them functions.

Good Luck !!
Last edited on
Hi again,

The count words function does enough to determine the position of the words, you should be able to record that info then make them using the string::substr function.

http://www.cplusplus.com/reference/string/string/substr/
Thanks to all of your help I solved it. The chapter from which I am doing the Programming Projects taught me about the
string::substr
function. This is what my
assign_names
function looks like now:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void assign_names(const string& name, int words, string& first, string& middle, string& last)
{
	int pos;
	string temp(name);

	if (words == 2)
	{
		pos = temp.find(' ');
		first = temp.substr(0, pos);
		last = temp.substr(pos + 1, temp.length() - pos);
	}
	else if (words == 3)
	{
		pos = temp.find(' ');
		first = temp.substr(0, pos);
		temp = temp.substr(pos + 1, temp.length() - pos);
		pos = temp.find(' ');
		middle = temp.substr(0, pos);
		last = temp.substr(pos + 1, temp.length() - pos);
	}
}


When I posted the earlier line:
- This is what my
assign_names
function looks like now-
I noticed that (assign_names) ends up on its own line. How do I get it to be in the middle of a line of output like the rest of you do?
Last edited on
I noticed that (assign_names) ends up on its own line. How do I get it to be in the middle of a line of output like the rest of you do?


Use the code tag button <> rather than the quote button.


Any thoughts on using a vector to put the names in?
Any thoughts on using a vector to put the names in?

This chapter did introduce vectors. Next time I study I'll solve this problem using them.

Thanks for the help!
Last edited on
So I tried to read a name into a vector from the keyboard, I used '\n' as the condition to end the read. When I run the program I input a name, but when I press enter, the loop doesn't end.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <vector>
using namespace std;

int main()
{
	vector<char> name;
	char next;
	int words;

	cout << "Enter name: ";
	cin >> next;
	while (next != '\n')
	{
		name.push_back(next);
		cin >> next;
	}
	for (unsigned int i = 0; i < name.size(); i++)
		cout << name[i];
	cout << endl;
	system("pause");
	return 0;
}

Why can't I used the end of line character to end the loop? I tried the character 'p' and the character '1', those worked, but the spaces in the name weren't read in. How do I read a line of text (including the spaces) into a vector?
Last edited on
Hi,

I meant a std::vector<std::string>

There are various ways to initialise such a vector:

std::vector<std::string> Legend = { "Elvis", "Aaron", "Presley"};

or one can push_back strings:

1
2
3
4
5
std::vector<std::string> Legend;

Legend.push_back("Elvis");
Legend.push_back("Aaron");
Legend.push_back("Presley");


Good Luck !!
Topic archived. No new replies allowed.