pulling words from strings

I'm just beginning to learn C++ and I'm having some issues with this function I'm trying to make. Basically I have a string and I want to pull out individual words from this string, but when I run this function i keep getting an out of range exception. is there an easier way to create this function? I know spaces exist in the entryString. I've looked into type casting too, I'm not sure if I have to cast the char findChar as a string before I append, any help would be amazing :D

*edit* I had to set findChar to something before the while statement would work.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
string disectString(string entryString)
{

	string exitString = "";
	char findChar = 'a';
	int i = 0;	

	while(findChar != ' ')		
	{
		findChar = entryString.at(i);	
		exitString += findChar;
		i++;
	}

	return exitString;
}
Last edited on
1
2
3
4
5
6
std::string GetNthWord(std::string s, std::size_t n)
{
    std::istringstream iss (s);
    while(n-- > 0 && (iss >> s));
    return s;
}
http://ideone.com/1UXg6z

Explanation:
The parameter s is passed by value, so a copy is made. We use this initial value to make an input string stream so we can extract space-delimited words. We then extract into s because we don't need its original value anymore. We do so over and over until either we reach the nth word, or the extraction operation fails. We then return s. If the extraction operation fails, s will either have the last extracted word, or if no words were ever extracted it will return the original string (which would be empty or only spaces).
Last edited on
closed account (3qX21hU5)
Your ouput worked fine for me. Could you paste your code here for us?

I usually don't do this but you seem like you put in the effort on figuring this out so here is a function that splits a string up word by word. Make sure you understand exactly what everything does and what is going on before you use it. Look into the string member functions find_first_of() and substr() because they are important.

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

using namespace std;

void splitString(const string &str, vector<string> &output)
{
    string::size_type start = 0; // Where to start
    string::size_type last = str.find_first_of(" "); // Finds the first space

    // npos means that the find_first_of wasn't able to find what it was looking for
    // in this case it means it couldn't find another space so we are at the end of the
    // words in the string.
    while (last != string::npos)
    {
        // If last is greater then start we have a word ready
        if (last > start)
        {
            output.push_back(str.substr(start, last - start)); // Puts the word into a vector look into how the method substr() works
        }

        start = ++last; // Reset start to the first character of the next word
        last = str.find_first_of(" ", last); // This means find the first space and we start searching at the first character of the next word
    }

    // This will pickup the last word in the file since it won't be added to the vector inside our loop
    output.push_back(str.substr(start));
}

int main()
{
    string myString("how are you doing");
    vector<string> words;
    splitString(myString, words);

    for (auto i = 0; i != words.size(); ++i)
        cout << words[i] << endl;
}


Anyways if you have any question feel free to ask and we will help answer them.
Thank you Zereo! I don't understand your Function L B, I haven't had much work with streams. but Zereo, yours makes some sense. I've seen size_type before but as far as I understand its sorta like an int?

splitString will basically pass in a constant (unchanged) string by reference (so its memory location is changed and thus by passing the issue of losing all changes when exiting the scope of the function) it will then pull each word out and put it into a vector of words.

well here's my Code. basically my project is to map the stars in the sky. I have a text file that I've been given with all the points. I've pulled each line out of the text and will next put them into a linked list to be then processed and printed. (that's next part I'll be working on) but this has had me stuck all day and none of my books have been able to help really.

the reading of the file I got actually from this site I believe, atleast it helped me understand

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
//all the files to include
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

using namespace std;

//class that holds that needed code for list
//it will hold all the data for each star
//and be a processable list to be printed out
class LinkList
{
	private:
		struct node
		{
			string xAxis;			//for x axis of star
			string yAxis;			//for y axis of star
			string zAxis;			//for z axis of star, not important but still added
			string extraOne;			//If more data exists, it goes here
			string extraTwo;			//not all entries have 7 items of 
			string extraThree;			//data, these should be null unless 
			string extraFour;			//something exists
			struct node* next;		//for next star in the list
		};
		node* head;					//specifies beginning of list
		node* tail;					//specifies end of list
	public:	
		void add(string);			//for adding a star
		void print();				//prints out the list, test purposes really
};

string disectString(string entryString)
{

	string exitString = "";
	char findChar = 'a';
	int i = 0;	

	while(findChar != ' ')		
	{
		findChar = entryString.at(i);	
		exitString += findChar;
		i++;
	}

	return exitString;
}

int main()
{
	string line;						//creates a holder for each line of code
	string testString;
	ifstream starFile ("example.txt");		//reads the file
	if (starFile.is_open())				//if the file is open, do the following
	{
		while (starFile.good())			//while there's stuff in the file
		{
			getline(starFile, line);		//get the line and put it into object line
			cout << line << endl;		//print out the line (later it will be add it to linked list

			testString = disectString(line);	// it stops here

			cout << testString << endl;
			
		}
		starFile.close();				//close file when done
	}
	else								//if else statement to fall back to
	{
		cout << "issues found";
	}

	cin >> line;
	return 0;
}

//adds a star to the list, it will take a string and break it down into its respective entries
void LinkList::add(string info)
{
	
}

//basic print out, it just shows the x, y and z axis for the stars added
void LinkList::print()
{
	node* current = head;
	cout << "X:" << current->xAxis << "\tY:" << current->yAxis << "\tZ:" << current->zAxis << endl;
	current = current->next;
}
Here is a simplified version of Zereo's code:
1
2
3
4
5
6
7
8
9
10
std::vector<std::string> SplitWords(std::string s)
{
    std::istringstream iss (s);
    std::vector<std::string> v;
    while(iss >> s)
    {
        v.push_back(s);
    }
    return v;
}
http://ideone.com/R9RJCf <---check it out
Last edited on
wow. I'm looking into L B's code and that's really powerful for the amount of coding that is actually in that function. How does that work really? the istringstream?

also Zereo, I have worked with substr before, basically it takes 2 parameters of type int, and will look in a string after int 1's location and subtract all characters between that and int 2's location in the string.

I've worked with push_back before too, that is a part of the vector class. it inserts an object at the end of the vector. (it your case it inserts the string of characters between the first and last values)

your function then sets the first value to the last (+1 because thats the next character in the string) then finds the next ending of the word and repeats.

thank you for helping but why did my code fail?
Urbatin wrote:
wow. I'm looking into L B's code and that's really powerful for the amount of coding that is actually in that function. How does that work really? the istringstream?
std::istringstream can be constructed from a std::string, and basically works the same as std::cin except with the string you give it instead of user input. The formatted extraction operator >> will read into a std::string until it hits a space, then it gives up. It also returns the stream you just read from (which is why you can chain >> the >> operator >> for >> multiple >> variables), which, when inside an if statement or while loop, gets converted to a boolean that indicates whether the stream is OK. When the stream runs out of data it is no longer OK, so it stops looping.
Last edited on
closed account (3qX21hU5)
I always forget about stringstreams for some reason lol oh well ;p nice code though LB
Much love! the istringstream worked excellent and makes it easier to handle the data I have. I'm going to have to read up on this, it gets the job done but I'm still a little meh with it.

but basically its just another location for objects to be retrieved from and it already treats spaces and return characters the way I want it to?
Yes, it is an istream like std::cin is ;)
closed account (3qX21hU5)
and it already treats spaces and return characters the way I want it to?


Correct, stringsteams are a very powerful tool that you can use. Another common use for them is when you need extract numbers from a string.

For example lets say we have a string that looks like this "Age 200" and you needed to get that 200 into a integer so you can do some math on it. You could do something like this

1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
    string words("Age 200");
    istringstream in(words);

    string temp; // Holds the words we don't want
    int age;

    in >> temp >> age;

    cout << age + 10;
}


There are other useful ways to use it also so it is a very good thing to learn about.
Topic archived. No new replies allowed.