Detecting a sentence ending with "?", "!",

Pages: 12
Hi Guys.

I'm trying to write amend the code below to detect when a sentence ends with "?", "!", and not just "." ( full stop). Basically the code accepts a file with text in it, it then ask the user to enter words to search for. then outputs the sentences which the words appear, also in the order the sentences appear in the main text. My problem is that i cant get it to detect sentences that end with "?", "!" or even e.t.c.

2, i am trying to make the program search for multiple word phrases not just one word.
Below is my code. i would be happy if i get some one to help amend it or put me on track.


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
#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
using namespace std;


int main()
{
	ifstream inFile;
	string filePath;
	string tempString;
	stringstream ss;
	vector<string> words;
	vector<string> sentence;

	cout << " User-Query Based Automatic summarizer  " << endl << endl;

	cout << "Please enter the file path that contains the text to be summarized: ";
	getline(cin, filePath);
	cout << endl;

	//opens the input file
	inFile.open(filePath);

	//makes sure the input file opened successfully
	if (!inFile)
	{
		cout << "Error unable to open file " << filePath << " Program terminated";
		cin.ignore();
		exit(1);
	}
	else { cout << "      File Found !" << endl<<endl; }

	cout << "Please enter the words to be used in generating your summary (Please seperate each word with spaces )  then press enter when done: ";
	getline(cin, tempString);
	cout << endl;
	cout << endl;
	ss << tempString;

	//extracts individual words into a vector
	while (ss >> tempString)
	{
		words.push_back(tempString);
	}


	//loops through a file until input fails
	while (getline(inFile, tempString, '.') || getline(inFile, tempString, '?') )
	{
		//loops through the words vector 
		for (size_t i = 0; i < words.size(); i++)
		{
			//checks to see if a word can be found in tempString
			if (tempString.find(words[i]) != std::string::npos)
			{
				//removes any newlines in the string
				while (tempString.front() == '\n' || tempString.front() == ' ')
					tempString = tempString.substr(1, tempString.size() - 1);
				while (tempString.back() == '\n' || tempString.back() == ' ')
					tempString = tempString.substr(0, tempString.size() - 2);
				tempString += "." ;
				/*tempString += "?";*/

				sentence.push_back(tempString);
				break;
			}
			
		}
	}


	
	//prints a vector
	for (int i = 0; i < sentence.size(); i++)
	{
		cout << sentence[i]  << endl;
	}

	cin.ignore();
		return 0;
}
Line 52 isn't good. The first getline won't fail until there is nothing left to extract from the input. The second getline won't be called until the first fails and since there is nothing left to extract from the input stream it will always fail.

There are several ways you can go about this, but the simplest is to read each character in one by one and build the string to push_back into sentence as you go.
@cire thanks. i understand what you mean. but is there any way to amend the above one so that it recognizes the other characters as an end line too
You can make one

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <istream>
#include <string>
#include <iterator>
#include <unordered_set>

std::istream &getline_wdelim(std::istream &iss, std::string &buf, const char *args = "\n\r")
{
	static std::unordered_set<char> delims(&args[0], &args[sizeof (args)]);
	char ch;
	buf.clear();
	
	while (iss.get(ch) && delims.count(ch) == 0)
		buf.push_back(ch);
	
	if (iss)
		buf.push_back(ch);
		
	return iss;
}
@smac89 thank alot i dont understand your code... can you please explain it?
Ignore that one, here is a revised version:

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
#include <iostream>
#include <istream>
#include <string>
#include <cstring>
#include <unordered_set>

class getline_wdelim
{
    std::unordered_set<char> delims;
	std::istream &iss;
	bool flags_set;
	int predicate (char ch)
	{
		return flags_set ? delims.count(ch) == 0 : ch != '\n' && ch != '\r';
	}
	
public:
	explicit getline_wdelim(std::istream &iss)
		:iss(iss)
		,flags_set(false)
	{}
	
	// Resets the delimiter flags
	void reset(const char *args)
	{
		delims.clear();
		size_t len = strlen(args);
		flags_set = len > 0;
		delims.insert(&args[0], &args[len]);
	}
	
	// reads string from stdin until a delimiter is met
	// This delimiter is read and discarded
	std::istream& getline(std::string &buf)
	{
		buf.clear();
		
		char ch;
		while (iss.get(ch) && predicate(ch))
			buf.push_back(ch);
	
		if (iss && buf.length() == 0) return getline(buf);
		else if (buf.length() > 0) iss.clear();
			
		return iss;
	}
	
	// resets the delimiters of the current getline_wdelim object
	// reads string from stdin until a delimiter is met
	// This delimiter is discarded
	std::istream& getline(std::string &buf, const char *args)
	{
		buf.clear();
		this->reset(args);
		
		char ch;
		while (iss.get(ch) && predicate(ch))
			buf.push_back(ch);
	
		if (iss && buf.length() == 0) return getline(buf);
		else if (buf.length() > 0) iss.clear();
		return iss;
	}
};

int main()
{
	std::string mystr;
	getline_wdelim obj(std::cin);
	
	if ( obj.getline(mystr, ".?!") )
		std::cout << mystr << std::endl;
	
	if ( obj.getline(mystr) )
		std::cout << mystr << std::endl;
		
	if ( obj.getline(mystr) )
		std::cout << mystr << std::endl;
	
	if ( obj.getline(mystr) )
		std::cout << mystr << std::endl;
	
	if (obj.getline(mystr)) // nothing left to read...
		std::cout << mystr << std::endl;
		
	return 0;
}


Input:
This is a line.Is this a line?Another line!
Last line


Output:
This is a line
Is this a line
Another line
Last line



In your case the usage will be:
(Assuming you already initialised the object)

1
2
3
obj.reset("?.");
while (obj.getline(tempString))
{ ... }
Last edited on
@smac89. thank for the help, unfortunately i have not gotten to that stage that i will understand your code. can you please proffer a simplistic approach to the code. its had for me to understand.
Thanks
its had for me to understand.


What smac89 is doing, in a rather verbose way, is exactly what I recommended: read in the file char by char and construct a string as you go.

Here is another approach:

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
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>

// We encapsulate the building of the "line" here.
// readline is a function which takes a reference to an input stream
// (such as a file), a reference to a string in which to store the extracted
// string and a list of characters in the form of a string which can indicate 
// the end of a line
std::istream& readline(std::istream& is, std::string& result, std::string line_endings)
{
    result.clear();                         // empty result
    is >> std::ws;                          // consume leading whitespace 

    bool end_of_line = false;
    char ch;

    while (!end_of_line && is.get(ch))      // extract a character from the input stream
    {
        // is it a character which can indicate an end of line?
        if (line_endings.find(ch) != std::string::npos)
            end_of_line = true;

        result += ch;
    }

    // If we extracted characters, but encountered the end of file before we reached
    // a character that indicates the end of a line, we still want to signal success:
    if (result.size())
        is.clear();

    return is;
}

// replace newlines in a string with spaces.
std::string remove_newlines(std::string str)
{
    for (std::size_t i = 0; i < str.length(); ++i)
        if (str[i] == '\n')
            str[i] = ' ';

    return str;
}

// replace with std::ifstream in(filename)
std::istringstream in("This\nspans\nmultiple\nlines. This does not! "
                      "Nor does this? But,\nthis one does.");

int main()
{
    std::vector<std::string> lines;

    std::string line;
    while (readline(in, line, "!.?"))
    {
        line = remove_newlines(line);
        lines.push_back(line);
    }

    for (unsigned line_no = 0; line_no < lines.size(); ++line_no)
        std::cout << line_no + 1 << ": " << lines[line_no] << '\n';
}


1: This spans multiple lines.
2: This does not!
3: Nor does this?
4: But, this one does.



If you are familiar with C style IO, then the other option is fscanf or a combination of fgets and sscanf

http://www.cplusplus.com/reference/cstdio/

If I think of an uncomplicated method I will post here
> Basically the code accepts a file with text in it, it then ask the user to enter words to search for.
> outputs the sentences which the words appear, in the order the sentences appear in the main text.

TODO: i am trying to make the program search for multiple word phrases not just one word.

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
#include <vector>
#include <map>
#include <string>
#include <cctype>
#include <utility>
#include <sstream>
#include <iostream>

using seq_type = std::vector<std::string> ; // sentences

// map word => position in sentences sequence
using map_type = std::multimap< std::string, std::size_t > ;

std::string sanitize( std::string word )
{
    std::string result ;
    for( char c : word ) if( std::isalnum(c) ) result += std::tolower(c) ;
    return result ;
}

std::pair<map_type,seq_type> make_map( std::istream& stm, std::string end_chars = ".?!" )
{
    map_type map ;
    seq_type seq(1) ;

    std::string word ;
    while( stm >> word )
    {
        seq.back() += word ;
        map.emplace( sanitize(word), seq.size() - 1 ) ;

        if( end_chars.find( word.back() ) != std::string::npos ) seq.push_back("") ;
        else seq.back() += ' ' ;
    }

    if( seq.back().empty() ) seq.pop_back() ;
    return { map, seq } ;
}

int main()
{
    std::istringstream file
    ( R"(
        Shall I compare thee to a summer's day? Thou art
        more lovely and more temperate. Rough winds do
        shake the darling buds of May! And summer's lease
        hath all too short a date. Sometime too hot the eye
        of heaven shines. And often is his gold complexion dimm'd!
        And every fair from fair sometime declines. By chance,
        or nature's changing course untrimm'd.
    )" );

    const auto pair = make_map(file) ;
    const map_type& map = pair.first ;
    const seq_type& seq = pair.second ;

    std::cout << "-------   sentences    --------------------\n" ;
    for( std::size_t i = 0 ; i < seq.size() ; ++i )
        std::cout << i << ". " << seq[i] << '\n' ;

    std::cout << "\n-------   look up    --------------------\n" ;
    for( const auto& s : { "lovely", "and", "day!!!", "date", "zebra", "thou", "The" } )
    {
        std::cout << s << '\n' ;
        auto bounds = map.equal_range( sanitize(s) ) ;
        for( auto iter = bounds.first ; iter != bounds.second ; ++iter )
            std::cout << '\t' << iter->second << ". " << seq[iter->second] << '\n' ;
        std::cout << "\n\n" ;
    }
}

http://coliru.stacked-crooked.com/a/fb772160c61f8feb
@JLborges Now my brain is about to explode... am not that an expert . i still dont understand it. been looking at your code trying to read meaning to it but it still too advanced for me.
all i want to know is how can i amend my code so that it sees a "?" or "!" too as a sentence delimiter not just only full stop.
i tried modifying it below using a for loop to check the character of the strings in a sentence then changes the default delimiter .. but i think am getting it wrong somewhere.


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
#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
using namespace std;


int main()
{
	char question = '?';
	
	char exclamation = '!';
	char TempAssign = 0;
	ifstream inFile;
	string filePath;
	string tempString;
	stringstream ss;
	vector<string> words;
	vector<string> sentence;

	cout << " User-Query Based Automatic summarizer  " << endl << endl;

	cout << "Please enter the file path that contains the text to be summarized: ";
	getline(cin, filePath);
	cout << endl;

	//opens the input file
	inFile.open(filePath);

	//makes sure the input file opened successfully
	if (!inFile)
	{
		cout << "Error unable to open file " << filePath << " Program terminated";
		cin.ignore();
		exit(1);
	}
	else { cout << "      File Found !" << endl<<endl; }

	cout << "Please enter the words to be used in generating your summary (Please seperate each word with spaces )  then press enter when done: ";
	getline(cin, tempString);
	cout << endl;
	cout << endl;
	ss << tempString;

	//extracts individual words into a vector
	while (ss >> tempString)
	{
		words.push_back(tempString);
	}


			

		//loops through a file until input fails
		while (getline(inFile, tempString, TempAssign))  // reads through every line using "." as a sentence delimeter
		{
					/*cout << TempAssign << endl;*/

			//loops through the words vector 
			for (size_t i = 0; i < words.size(); i++)
			{ 
				for ( int n = 0; n < tempString.size (); n ++)
									{

										
										if ( tempString[n] == '?')
										{
											TempAssign = '?';
											break;
										}
		
										else if ( tempString[n] == '!')
										{
											TempAssign = '!';
											break;
										}
										else  if (TempAssign =='.' )
										{
											TempAssign = '.';
										break;
										}
		
									}
				//checks to see if a word can be found in tempString
				if (tempString.find(words[i]) != std::string::npos)
				{
					//removes any newlines in the string
					while (tempString.front() == '\n' || tempString.front() == ' ')
						tempString = tempString.substr(1, tempString.size() - 1);
					while (tempString.back() == '\n' || tempString.back() == ' ')
						tempString = tempString.substr(0, tempString.size() - 2);
					/*tempString += "." ;*/
					/*tempString += "?";*/

					sentence.push_back(tempString);
					break;
				}
			
			}
		}
	
	

	
	//prints a vector
	for (int i = 0; i < sentence.size(); i++)
	{
		cout << sentence[i]  << endl;
	}

	cin.ignore();
		return 0;
}
> all i want to know is how can i amend my code so that it sees a "?" or "!" too as a sentence delimiter
> not just only full stop.

Something like this (untested):

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
#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
using namespace std;


int main()
{
    /*
    char question = '?';

    char exclamation = '!';
    */

    //char TempAssign = 0;
    //ifstream inFile;
    //string filePath;
    //string tempString;
    //stringstream ss;
    // vector<string> words;
    //vector<string> sentence;

    cout << " User-Query Based Automatic summarizer  " << /*endl*/ '\n' << /*endl*/ '\n';

    cout << "Please enter the file path that contains the text to be summarized: ";
    string filePath ;
    getline(cin, filePath);
    cout << /*endl*/ '\n';

    //opens the input file
    // inFile.open(filePath);
    ifstream inFile(filePath) ;

    //makes sure the input file opened successfully
    if (!inFile)
    {
        cout << "Error unable to open file " << filePath << " Program terminated";
        // cin.ignore();
        exit(1);
    }
    else
    {
        cout << "      File Found !" << /*endl*/ '\n'<</*endl*/ '\n';
    }

    cout << "Please enter the words to be used in generating your summary "
            "(Please seperate each word with spaces )  then press enter when done: ";

    string tempString;
    getline(cin, tempString);

    cout << /*endl*/ '\n';
    cout << /*endl*/ '\n';
    // ss << tempString;

    istringstream ss(tempString) ;

    vector<string> words;

    //extracts individual words into a vector
    while (ss >> tempString )
    {
        words.push_back(tempString);
    }


    //loops through a file until input fails
    //while (getline(inFile, tempString, TempAssign))
    // reads through every line using "." as a sentence delimeter

    vector<string> sentence ;
    string curr_sentence ; // current sentence being built
    string curr_word ; // the word just read
    const string sentence_enders = "?!." ;

    // read word by word from the file until input fails
    while( inFile >> curr_word ) // for each word read
    {
        curr_sentence += curr_word ; // add word to current sentence

        // if the current word ends with a sentence ender
        if( sentence_enders.find( curr_word.back() ) != string::npos )
        // or: if( sentence_enders.find( curr_word[ curr_word.size() - 1 ] ) != string::npos )
        {
            // this is the end of the sentence.
            sentence.push_back( curr_sentence ) ; // add current sentence to sentence vector
            curr_sentence= "" ; // and begin a new empty sentence
        }

        else curr_sentence += ' ' ; // put a space between this and the next word
    }

    // add the last sentence even if no sentence ender was found
    if( !curr_sentence.empty() ) sentence.push_back( curr_sentence ) ;


    //prints a vector
    for (int i = 0; i < sentence.size(); i++)
    {
        cout << sentence[i]  << /*endl*/ '\n';
    }

    //cin.ignore();
    //return 0;

    // TODO: search for the words
}

@JLborges Something like this (untested):

am having the same error in the previous code i pasted. instead of outputting the sentence with the search word, it outputs the whole original text. can you please check again when you are less busy

i also tried this other way but still am not getting it right.

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
#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <fstream>


using namespace std;

vector<string> split(const string &s, char delim);
bool searchWord(string line, string topic);


int main(){

	string text; string filepath;
	vector <string> myvec; string line;
	string word;

	cout << " enter file Dest"<< endl;
	cin >> filepath;
	cout << "Enter words" << endl;
	do { cin >> word;
	myvec.push_back (word);
	} while (myvec.size() < 4);

	/*getline(cin, word);*/

	ifstream file (filepath); // declaring file that contains the data inputs
	while( std::getline( file, line) )
	{	
		text += line;
	
	}
	

	/*vector<string> words = split(word, ' ');*/
	vector<string> paragraphs = split(text, '?!.');


	for (int j = 0; j < word.size(); j++)
	{
	
	for (unsigned i = 0; i < paragraphs.size(); i++)
	{
		if (searchWord(paragraphs.at(i), myvec[j]))
		{
			std::cout << ' ' << paragraphs.at(i);
			std::cout << '\n'; std::cout << '\n';
			paragraphs.erase(paragraphs.begin() + i);
		}		
	}

	}
	cout << "";	
}

bool searchWord(string line, string topic)
{
	bool found = false;

	size_t location;

	location = line.find(topic);

	if (location != string::npos)
	{
		found = true;		
	}

	return found;

}

vector<string> split(const string &s, char delim)
{
	vector<string> elems;	
	stringstream ss(s);
	string item;
	while (getline(ss, item, delim)) {
		elems.push_back(item);
	}
	return elems;

	
}
> can you please check again when you are less busy

Cursorily tested. Seems ok.

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

int main()
{
    // create a test file
    const char* const file_name =  "test_file.txt" ;
    {
        const std::string text =
            "Shall I compare thee to a summer's day? Thou art\n"
            "more lovely and more temperate. Rough winds do\n"
            "shake the darling buds of May! And summer's lease\n"
            "hath all too short a date. Sometime too hot the eye\n"
            "of heaven shines. And often is his gold complexion dimm'd!\n"
            "And every fair from fair sometime declines. By chance,\n"
            "or nature's changing course untrimm'd.\n" ;
        std::ofstream test_file(file_name); 
        test_file << text ;
    }
    
    // verify that the test file has been created correctly
    { 
        std::cout << "\n-------- the file contains ------------------\n"
                  << std::ifstream(file_name).rdbuf() 
                  << "------------------------------------------------\n" ;
    }
    
    std::ifstream inFile(file_name) ; // open the file for input
    
    vector<string> sentence ;
    string curr_sentence ; // current sentence being built
    string curr_word ; // the word just read
    const string sentence_enders = "?!." ;

    // read word by word from the file until input fails
    while( inFile >> curr_word ) // for each word read
    {
        curr_sentence += curr_word ; // add word to current sentence

        // if the current word ends with a sentence ender
        if( sentence_enders.find( curr_word[ curr_word.size() - 1 ] ) != string::npos )
        {
            // this is the end of the sentence.
            sentence.push_back( curr_sentence ) ; // add current sentence to sentence vector
            curr_sentence= "" ; // and begin a new empty sentence
        }

        else curr_sentence += ' ' ; // put a space between this and the next word
    }

    // add the last sentence even if no sentence ender was found
    if( !curr_sentence.empty() ) sentence.push_back( curr_sentence ) ;


    std::cout << "sentences extracted:\n--------------------\n" ;
    for ( std::size_t i = 0; i < sentence.size(); i++)
    {
        cout << '\t' << i << ". " << sentence[i]  << /*endl*/ '\n';
    }
}

clang++ -std=c++98 -stdlib=libc++ -Wall -Wextra -pedantic-errors -O3 main.cpp -lsupc++ && ./a.out
-------- the file contains ------------------
Shall I compare thee to a summer's day? Thou art
more lovely and more temperate. Rough winds do
shake the darling buds of May! And summer's lease
hath all too short a date. Sometime too hot the eye
of heaven shines. And often is his gold complexion dimm'd!
And every fair from fair sometime declines. By chance,
or nature's changing course untrimm'd.
------------------------------------------------
sentences extracted:
--------------------
	0. Shall I compare thee to a summer's day?
	1. Thou art more lovely and more temperate.
	2. Rough winds do shake the darling buds of May!
	3. And summer's lease hath all too short a date.
	4. Sometime too hot the eye of heaven shines.
	5. And often is his gold complexion dimm'd!
	6. And every fair from fair sometime declines.
	7. By chance, or nature's changing course untrimm'd.

http://coliru.stacked-crooked.com/a/01d98a53bab1f896
@JLborges thanks alot. i have some questions.

1, how do i modify your code to read from a file if i want to.
2, how do i input specific words to be searched because your code doesn't seem to do that.


Thanks
> 1, how do i modify your code to read from a file if i want to.

It is already reading from a test file.

To read from any file: delete lines 10 to 31, and provide the name of the file as file_name (line 32).


> how do i input specific words to be searched because your code doesn't seem to do that.

It's there in the earlier code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    cout << "Please enter the words to be used in generating your summary "
            "(Please seperate each word with spaces )  then press enter when done: ";
    string tempString;
    getline(cin, tempString);

    istringstream ss(tempString) ;

    vector<string> words;

    //extracts individual words into a vector
    while (ss >> tempString )
    {
        words.push_back(tempString);
    }


1, how do i modify your code to read from a file if i want to.

Erm.. it already does that.


2, how do i input specific words to be searched because your code doesn't seem to do that.

Why don't you tell us how you think you'd modify it to do that? From the code you can see how to search in a string for a particular char. It's not so different to search in a string for a particular sequence of chars (i.e. another string.)

It's not so good to just keep asking "how" without at least attempting to find a solution. It's doubly bad to ask "how" when the code already shows you exactly "how."

In the last code you posted '?!.' (line 38) is not a char, and again, you cannot use getline to accomplish what you want here (why do you continue to try after being given so many examples that don't use it?)
@cire am sorry if i seem like am lazy to do some things. am trying hard myself. i prefer it being explained rather being solved for me. thanks alot for your help .

@jlborges, i modified the code now. but it seems to search for the sentence enders then list the sentences. do need to add another code to do the searching seperately?

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

int main()
{

	ifstream inFile;
	string file_name;

	cout << "Please enter the file path that contains the text to be summarized: ";
	getline(cin, file_name);
	cout << endl;
	
	//opens the input file
	inFile.open(file_name);

	//makes sure the input file opened successfully
	if (!inFile)
	{
		cout << "Error unable to open file " << file_name << " Program terminated";
		cin.ignore();
		exit(1);
	}
	else { cout << "      File Found !" << endl<<endl; }

	 cout << "Please enter the words to be used in generating your summary "
            "(Please seperate each word with spaces )  then press enter when done: ";
    string tempString;
    getline(cin, tempString);

    istringstream ss(tempString) ;

    vector<string> curr_word ;

    //extracts individual words into a vector
    while (ss >> tempString )
    {
        curr_word.push_back(tempString);
    }



    vector<string> sentence ;
    string curr_sentence ; // current sentence being built
    /*string curr_word ;*/ // the word just read
    const string sentence_enders = "?!." ;

    // read word by word from the file until input fails
    while( inFile >> tempString ) // for each word read
    {
        curr_sentence += tempString ; // add word to current sentence

        // if the current word ends with a sentence ender
        if( sentence_enders.find( tempString[ tempString.size() - 1 ] ) != string::npos )
        {
            // this is the end of the sentence.
            sentence.push_back( curr_sentence ) ; // add current sentence to sentence vector
            curr_sentence= "" ; // and begin a new empty sentence
        }

        else curr_sentence += ' ' ; // put a space between this and the next word
    }

    // add the last sentence even if no sentence ender was found
    if( !curr_sentence.empty() ) sentence.push_back( curr_sentence ) ;


    std::cout << "sentences extracted:\n--------------------\n" ;
    for ( std::size_t i = 0; i < sentence.size(); i++)
    {
        cout << '\t' << i << ". " << sentence[i]  << /*endl*/ '\n';
    }
}
@cire , @JLBorges or anybody can you please tell me what am doing wrong ?

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
#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <fstream>
using namespace std;
bool searchWord(string line, string topic);
int main()
{

	ifstream inFile;
	string file_name;
	string tempString;
    istringstream ss(tempString) ;
    string curr_word ;
	vector <string> word;

	

	cout << "Please enter the file path that contains the text to be summarized: ";
	getline(cin, file_name);
	cout << endl;
	
	//opens the input file
	inFile.open(file_name);

	//makes sure the input file opened successfully
	if (!inFile)
	{
		cout << "Error unable to open file " << file_name << " Program terminated";
		cin.ignore();
		exit(1);
	}
	else { cout << "      File Found !" << endl<<endl; }

	 cout << "Please enter the words to be used in generating your summary "
            "(Please seperate each word with spaces )  then press enter when done: ";
    getline(cin, tempString);

    //extracts individual words into a vector
    while (ss >> tempString )
    {
        word.push_back(tempString);
    }

    vector<string> sentence ;
    string curr_sentence ; // current sentence being built
    
    const string sentence_enders = "?!." ;

    // read word by word from the file until input fails
    while( inFile >> curr_word ) // for each word read
    {
        curr_sentence += curr_word ; // add word to current sentence

        // if the current word ends with a sentence ender
			if( sentence_enders.find( curr_word[ curr_word.size() - 1 ] ) != string::npos )
			{
				// this is the end of the sentence.
				sentence.push_back( curr_sentence ) ; // add current sentence to sentence vector
				curr_sentence= "" ; // and begin a new empty sentence
			}

			else curr_sentence += ' ' ; // put a space between this and the next word
    }

    // add the last sentence even if no sentence ender was found
    if( !curr_sentence.empty() ) sentence.push_back( curr_sentence ) ;


    std::cout << "sentences extracted:\n--------------------\n" ;
    for ( std::size_t i = 0; i < sentence.size(); i++)
    {
        cout << '\t' << i << ". " << sentence[i]  << /*endl*/ '\n';
    }


	for (int j = 0; j < word.size(); j++)
	{
	
		for (std::size_t  n = 0; n < sentence.size(); n++)
		{
			if (searchWord(sentence[n], word[j]))
			{
				std::cout << ' ' << sentence[n];
				std::cout << '\n'; std::cout << '\n';
				sentence.erase(sentence.begin() + n);
			}		
		}

	}
	

}
bool searchWord(string line, string topic)
{
	bool found = false;

	size_t location;

	location = line.find(topic);

	if (location != string::npos)
	{
		found = true;		
	}

	return found;

}
Last edited on
Pages: 12