Iterating through a list of lists

Hi all!

I am trying to work with a list of lists ... just trying to do basic operations with it. I'm trying to use a list of lists to code a "text editing program" When I try to create the "inside" iterator the debugger sends me an error because of its creation.

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
list<list<string>> split(const list<string>& bulk){
	list<list<string>> splitdata;
	list<string>::const_iterator iterbulk; 
	list<string>::iterator iterls;
	list<list<string>>::iterator iterll;
	typedef string::size_type string_size;
	
	iterll = splitdata.begin();
	for(iterbulk = bulk.begin(); iterbulk != bulk.end(); ++iterbulk){
		string_size i= 0;
		iterls = (*iterll).begin(); // ERROR
		while (i != (*iterbulk).size())	{
			while (i != (*iterbulk).size() && isspace((*iterbulk)[i]))
			++i;
			string_size j = i;
			while (j != (*iterbulk).size() && !isspace((*iterbulk)[j]))
			++j;
			if (i != j){
				string s=(*iterbulk).substr(i, j - i);
				(*iterls).push_back(s[0]);
				i=j;
				++iterls;
			}
		}
	++iterll;
	}
	return splitdata;
}
As the container splitdata is empty then after executing the statement

iterll = splitdata.begin();

iterll is equal to splitdata.end()

You are trying to dereference this iterator

iterls = (*iterll).begin();

So the behaviour of the program is undefined.
Last edited on
Thank you for the reply. I am still learning c++ and I have not noticed that behaviour.
I tried to solve it this way:
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
list<list<string>> split(const list<string>& bulk){
	list<list<string>> splitdata;
	list<string>::const_iterator iterbulk; 
	list<string>::iterator iterls;
	list<list<string>>::iterator iterll;
	typedef string::size_type string_size;

	list<list<string>>::size_type n = bulk.size();
	splitdata.resize(n);
	iterll = splitdata.begin();
	for(iterbulk = bulk.begin(); iterbulk != bulk.end(); ++iterbulk){
		string_size i= 0;
		list<string>::size_type m = 7;
		(*iterll).resize(m);
		iterls = (*iterll).begin(); 
		while (i != (*iterbulk).size())	{
			while (i != (*iterbulk).size() && isspace((*iterbulk)[i]))
			++i;
			string_size j = i;
			while (j != (*iterbulk).size() && !isspace((*iterbulk)[j]))
			++j;
			if (i != j)	{ 
				string s=(*iterbulk).substr(i, j - i);
				(*iterls).push_back(s[0]);
				i=j;
				++iterls;
			}
		}
	++iterll;
	}
	return splitdata;
}

but it seems that is not the good one. Could you throw some light on how to solve it?. I am a bit lost.

Thank you in advance
Last edited on
Are you trying to split each string in a list into a list of space-separated strings? It could be done simpler, like this:

1
2
3
4
5
6
7
8
9
10
11
12
std::list<std::list<std::string>> split(const std::list<std::string>& bulk)
{
    std::list<std::list<std::string>> splitdata;
    for(auto& str: bulk)
    {
        std::istringstream buf(str);
        splitdata.emplace_back(
             std::istream_iterator<std::string>(buf),
             std::istream_iterator<std::string>());
    }
    return splitdata;
}


Live demo: http://ideone.com/WisBPK
Last edited on
Are you trying to split each string in a list into a list of space-separated strings? It could be done simpler, like this:
1
2
3
4
5
6
7
8
9
10
11
12
std::list<std::list<std::string>> split(const std::list<std::string>& bulk)
{
    std::list<std::list<std::string>> splitdata;
    for(auto& str: bulk)
    {
        std::istringstream buf(str);
        splitdata.emplace_back(
             std::istream_iterator<std::string>(buf),
             std::istream_iterator<std::string>());
    }
    return splitdata;
}


Yes, that is exactly what I am trying to do.
As I have noticed on the live demo ,your code nails it; but I am working with visual studio 2010 and here the code is not working at all :(
Thanks for your help!
Last edited on
That could be re-written using 1998 C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
std::list<std::list<std::string> > split(const std::list<std::string>& bulk)
{
    std::list<std::list<std::string> > splitdata;
    for( std::list<std::string>::const_iterator i = bulk.begin();
         i!=bulk.end();
       ++i)
    {
        std::istringstream buf(*i);
        splitdata.push_back( std::list<std::string>(
             std::istream_iterator<std::string>(buf),
             std::istream_iterator<std::string>()));
    }
    return splitdata;
}
Yes, the last one works perfect and it is far simpler than my first attempt.

Thank you very much again.
Topic archived. No new replies allowed.