String input and split

Mar 18, 2017 at 3:36pm
What is the easiest way to take string input from keyboard and then split this string based on how many words there are?

I've tried doing it the raw C++ way, but people said i can't and it's too hard. I should use STL instead. But how exactly? I can use vector <string> and take input from keyboard, if i'm not mistakig, but then how do you split it and store in a vector <string> again? This is a problem with general case, x long string and y words.

I need to do this, in order to have words stored and then calculate the frequency of how many times each word appears and display it like this.

word1 - 5 times

word2 - 3 times

word3 - 3 times

word4 - 1 times

word5 - 1 times

word5 - 1 times

word5 - 1 times
Mar 18, 2017 at 4:06pm
getline() from std::cin into std::string
intialize std::istringstream object, stream, with the string
declare another std::string temp
read the stream into temp (it's parsed on white-space) and while it's being read-in send the temp string to a std::map<std::string, int> using the [] operator for map's which would increment count of words already present in the map
for consistency you may also wish to remove punctuations and upper/lower case the string temp first
Mar 18, 2017 at 4:46pm
Something like this (more or less):
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
#include <exception>
#include <fstream>
#include <iostream>
#include <sstream>
#include <map>
#include <string>

int main ()
{
    std::map<std::string, int> words;
    try {
        std::ifstream textfile("exampletext.txt");
        std::stringstream tmpss;
        tmpss << textfile.rdbuf();
        std::string tmpstring;
        while(tmpss) {
            tmpss >> tmpstring;
            if(words.count(tmpstring))
                words.at(tmpstring) += 1;
            else
                words.emplace(tmpstring, 1);
        }
        textfile.close();
    } catch (std::exception& err) {
        std::cerr << "Error: " << err.what() << std::endl;
        exit(EXIT_FAILURE);
    }

    std::ofstream outtext("foundwords.txt");
    for(auto& tmppair : words)
        outtext << tmppair.first << ": " << tmppair.second << std::endl;

    return 0;
}

but it doesn't manage punctuations or upper/lower cases, as gunnerfunner wisely suggested.

I used sample text taken from here
http://randomtextgenerator.com/
to build a "exampletext.txt" file for testing.
Mar 18, 2017 at 4:59pm
Enoizat - unless OP shows some effort of their own try not to send out a full-fledged program, rather an outline to get them started (I must admit though that I have been guilty of this as well in the past)
Mar 18, 2017 at 4:59pm
I don't need punctuations atm, but what i'd really need is input from keyboard. Looks like you can do it only by using a file, is that right?
Mar 18, 2017 at 5:27pm
OP: read the two posts, what you're looking for is well within those two or raise specific queries if something is not clear
Last edited on Mar 18, 2017 at 5:28pm
Mar 18, 2017 at 7:43pm
Enoizat - unless OP shows some effort of their own try not to send out a full-fledged program, rather an outline to get them started

Hi, gunnerfunner.
Thank you for your directions. May I ask you if they are a personal position of yours or belong to the policy of this forum?
Thanks in advance for your answer.
Mar 18, 2017 at 9:30pm
To get the input from the keyboard use getline. To split the string use a stringstream and finally to count the frequency use a map<string, int>. Finally display all the words from the map.
Mar 18, 2017 at 9:33pm
@Enoizat,
here are the instructions how to ask and answer questions.
http://www.cplusplus.com/forum/beginner/1/
Mar 18, 2017 at 9:43pm
@Enoizat,
here are the instructions how to ask and answer questions.
http://www.cplusplus.com/forum/beginner/1/

Thank you, Thomas1965.
I read them when I subscribed this forum.
Is there any part which relates to what gunnerfunner said to me, in your opinion?
Thanks for your help.
Mar 18, 2017 at 9:55pm
Is there any part which relates to what gunnerfunner said to me, in your opinion?

No absoulut not.
Mar 19, 2017 at 7:53am
getline( cin, line );
will take a single line containing multiple words from the keyboard. To extract individual words use a stringstream and put them in a map<string,int>. That is presumably what the OP wants and what all the code samples and advice above correctly leads to.

However, just suppose that you were reading from file - why do you need a stringstream in that case? Surely you can just extract the words directly one by one from file anyway?
Mar 19, 2017 at 8:25am
why do you need a stringstream in that case? Surely you can just extract the words directly one by one from file anyway?

Sure you can, lastchance, and it will make the code much lighter!

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
#include <exception>
#include <fstream>
#include <iostream>
#include <map>
#include <string>

int main ()
{
    std::map<std::string, int> words;
    try {
        std::ifstream textfile("exampletext.txt");
        std::string tmpstring;
        while(textfile >> tmpstring) {
            if(words.count(tmpstring))
                words.at(tmpstring) += 1;
            else
                words.emplace(tmpstring, 1);
        }
        textfile.close();
    } catch (std::exception& err) {
        std::cerr << "Error: " << err.what() << std::endl;
        exit(EXIT_FAILURE);
    }

    std::ofstream outtext("foundwords.txt");
    for(auto& tmppair : words)
        outtext << tmppair.first << ": " << tmppair.second << std::endl;

    return 0;
}


Thank you for your correction.

Last edited on Mar 19, 2017 at 8:26am
Mar 19, 2017 at 11:11am
from OP:
What is the easiest way to take string input from keyboard

with the input coming from keyboard if std::istringstream is not used, another option could be std::regex
http://stackoverflow.com/questions/16749069/c-split-string-by-regex
Topic archived. No new replies allowed.