string::erase problem

closed account (EwCjE3v7)
Giving the input
example.
(not the period), this program gives a
Segmentation fault
.

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
int main()
{	
	map<string, size_t> word_count;
	set<string> exclude = {"the", "but", "and", "or", "an", "a"};


	string word;
	while (cin >> word) {
		for (auto beg = word.begin(); beg != word.end(); ++beg) {
			if (isalpha(*beg) && isupper(*beg)) {
				*beg = tolower(*beg);
			}
			if (ispunct(*beg)) {
				beg = word.erase(beg);
			}
		}

		if (exclude.find(word) == exclude.end())
			++word_count[word];
	}

	for (const auto &w : word_count) {
		cout << w.first << " occurs " << w.second << ((w.second > 1) ? " times" : " time") << endl;
	}

	return 0;
} 

Edit:

Went over what the for loop does and found the problem. After I initialise it from erase, it points at the last element and then the for loop increments that.

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
int main()
{	
	map<string, size_t> word_count;
	set<string> exclude = {"the", "but", "and", "or", "an", "a"};


	string word;
	while (cin >> word) {
		for (auto beg = word.begin(); beg != word.end(); ++beg) {
			if (isalpha(*beg) && isupper(*beg)) {
				*beg = tolower(*beg);
			}
			if (ispunct(*beg)) {
				beg = word.erase(beg) - 1;
			}
		}

		if (exclude.find(word) == exclude.end())
			++word_count[word];
	}

	for (const auto &w : word_count) {
		cout << w.first << " occurs " << w.second << ((w.second > 1) ? " times" : " time") << endl;
	}

	return 0;
}  
Last edited on
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
#include <iostream>
#include <map>
#include <string>
#include <cctype>
#include <set>

std::string sanitise( std::string str ) // remove punctuation, convert to lower case
{
    std::string sanitised ;
    for( char c : str ) // for each char in the string
    {
        if( !std::ispunct(c) ) sanitised += std::tolower(c) ;
    }

    return sanitised ;
}


int main()
{
	std::map< std::string, std::size_t > word_count;
	const std::set<std::string> exclude = {"the", "but", "and", "or", "an", "a"};

	std::string word;
	while ( std::cin >> word ) {

        word = sanitise(word) ;
        if( !word.empty() && exclude.find(word) == exclude.end() )  ++word_count[word];

	}

	for (const auto &w : word_count) {
		std::cout << w.first << " occurs " << w.second << ((w.second > 1) ? " times" : " time") << '\n' ;
	}
}
Last edited on
Topic archived. No new replies allowed.