split_iterator<string::iterator> example
hi, Can someone please tell me where I can find example of split_iteratorstring::iterator If I have 2 split_iteratorstring::iterators, how can I compare the 2 strings that the split_iterator pointing to? Thank you.
Hi, There is realy no magic there. You just need to realize, that you are not getting a string, rather a range. Range is a generalization of a pair of iterators. In case of split_iterator, these iterators point to first and one past the last character of the current token. Example can be found in /boost/libs/algorithm/string/example/split_example.cpp Regards, Pavol. Meryl Silverburgh wrote:
hi,
Can someone please tell me where I can find example of split_iteratorstring::iterator
If I have 2 split_iteratorstring::iterators, how can I compare the 2 strings that the split_iterator pointing to?
Thank you. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On 2/20/07, Pavol Droba
Hi,
There is realy no magic there. You just need to realize, that you are not getting a string, rather a range. Range is a generalization of a pair of iterators.
In case of split_iterator, these iterators point to first and one past the last character of the current token.
Example can be found in /boost/libs/algorithm/string/example/split_example.cpp
Regards, Pavol.
Thanks for your help. I have another question, how can I can i terminate the for loop when loop using string_split? class integer_compare { public: bool operator() (const string_split::value_type &a, const string_split::value_type &b) { // how can I iterate thru the string? how can i terminate the for loop? for (const string_split sitr = a; sitr != ???; sitr++) { // print out each substring (after '/' is stripped out) cout << copy_rangestd::string(*sitr) << endl; } return true; } };
Meryl Silverburgh wrote:
hi,
Can someone please tell me where I can find example of split_iteratorstring::iterator
If I have 2 split_iteratorstring::iterators, how can I compare the 2 strings that the split_iterator pointing to?
Thank you. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Meryl Silverburgh wrote:
On 2/20/07, Pavol Droba
wrote: Hi,
There is realy no magic there. You just need to realize, that you are not getting a string, rather a range. Range is a generalization of a pair of iterators.
In case of split_iterator, these iterators point to first and one past the last character of the current token.
Example can be found in /boost/libs/algorithm/string/example/split_example.cpp
Regards, Pavol.
Thanks for your help. I have another question, how can I can i terminate the for loop when loop using string_split?
class integer_compare { public: bool operator() (const string_split::value_type &a, const string_split::value_type &b) { // how can I iterate thru the string? how can i terminate the for loop?
for (const string_split sitr = a; sitr != ???; sitr++) {
// print out each substring (after '/' is stripped out) cout << copy_rangestd::string(*sitr) << endl;
} return true; } };
First of all, I don't understand your example. string_split::value_type is definitely not another split_iterator. it's type is (as I have mentioned in some previous mail) iterator_rangestring::iterator. As for the loop termination, default-initialized split_iterator (i.e. string_split) functions as a terminator. Alternatively you can check the eof() method. Regards, Pavol.
On 2/20/07, Pavol Droba
Meryl Silverburgh wrote:
On 2/20/07, Pavol Droba
wrote: Hi,
There is realy no magic there. You just need to realize, that you are not getting a string, rather a range. Range is a generalization of a pair of iterators.
In case of split_iterator, these iterators point to first and one past the last character of the current token.
Example can be found in /boost/libs/algorithm/string/example/split_example.cpp
Regards, Pavol.
Thanks for your help. I have another question, how can I can i terminate the for loop when loop using string_split?
class integer_compare { public: bool operator() (const string_split::value_type &a, const string_split::value_type &b) { // how can I iterate thru the string? how can i terminate the for loop?
for (const string_split sitr = a; sitr != ???; sitr++) {
// print out each substring (after '/' is stripped out) cout << copy_rangestd::string(*sitr) << endl;
} return true; } };
First of all, I don't understand your example. string_split::value_type is definitely not another split_iterator. it's type is (as I have mentioned in some previous mail) iterator_rangestring::iterator.
Pavol,
Thank for your help. I thought you said 'The question marks can be
substituted by
string_split::value_type'. In one of our previous exchange.
That is why I am using 'string_split::value_type' not
'iterator_rangestring::iterator'
Sorry if I mis-understand what you teach me.
From: Pavol Droba
The problem is with template instantiation. Since you are passing "string" and not "const string" as an argument to make_split_iterator, the resulting type is actualy split_iteratorstring::iterator. This is not the same (nor convertible) to split_iteratorstring::const_iterator.
So the simple fix would be to change the definition of the string_split to split_iteratorstring::iterator.
In addition, you will need to implement integer_compare.
In addition, you will need to implement integer_compare. I have not included it in may mail.
Thanks. I notice that. Can you please help me understand how to implement integer_compare (a predicate comparision object)?
What are the input type? bool operator() (const ? &a, const ? &b) ?
and if the input strings are '/1/1/5' and '1/1/10' what will be passed to the integer_compare?
It is an element comparison predicate therefore its arguments should be able to accept elements from the input sequence. So you have guessed the signature right. The question marks can be substituted by string_split::value_type. And that is an iterator_range pointing to a match found in the input string (iterator_rangestring::iterator)
As for the loop termination, default-initialized split_iterator (i.e. string_split) functions as a terminator. Alternatively you can check the eof() method.
Regards, Pavol. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Pavol,
Thank for your help. I thought you said 'The question marks can be substituted by string_split::value_type'. In one of our previous exchange.
That is why I am using 'string_split::value_type' not 'iterator_rangestring::iterator'
Sorry if I mis-understand what you teach me.
No worries. There is no problem with using string_split::value_type. It is just a typedef to iterator_rangestring::iterator. In your code, you misplaced it with string_split itself. Regards, Pavol.
On 2/20/07, Pavol Droba
Pavol,
Thank for your help. I thought you said 'The question marks can be substituted by string_split::value_type'. In one of our previous exchange.
That is why I am using 'string_split::value_type' not 'iterator_rangestring::iterator'
Sorry if I mis-understand what you teach me.
No worries.
There is no problem with using string_split::value_type. It is just a typedef to iterator_rangestring::iterator. In your code, you misplaced it with string_split itself.
I change the integer_compare class to use iterator_rangestring::iterator&.
And I am trying to loop thru the iterator_range inside the function()
of integer_compare:
bool operator() (const iterator_rangestring::iterator& a,
const iterator_rangestring::iterator& b) {
cout << "calling integer_compare " << endl;
// expect to print out "", "1", "1", "2" for a string of "/1/1/2"
for (string::iterator sitr = a.begin(); sitr != a.end(); sitr++) {
cout << copy_rangestd::string(*sitr) << endl;
}
return true;
}
But I get the following error saying I cant' instantiate
'boost::range_const_iterator<char>'.
Any more help is appreciated.
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"stringCompare.d"
-MT"stringCompare.d" -o"stringCompare.o" "../stringCompare.cpp"
../stringCompare.cpp:58:2: warning: no newline at end of file
/usr/include/boost/range/const_iterator.hpp: In instantiation of
'boost::range_const_iterator<char>':
/usr/include/boost/range/iterator_range.hpp:576: instantiated from
'SeqT boost::copy_range(const Range&) [with SeqT =
std::basic_string , Range = char]'
../stringCompare.cpp:28: instantiated from here
/usr/include/boost/range/const_iterator.hpp:36: error: 'char' is not a
class, struct, or union type
/usr/include/boost/range/iterator.hpp: In instantiation of
'boost::range_iterator<char>':
/usr/include/boost/range/iterator_range.hpp:576: instantiated from
'SeqT boost::copy_range(const Range&) [with SeqT =
std::basic_string Regards,
Pavol.
_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hi, Meryl Silverburgh wrote:
On 2/20/07, Pavol Droba
wrote: Pavol,
Thank for your help. I thought you said 'The question marks can be substituted by string_split::value_type'. In one of our previous exchange.
That is why I am using 'string_split::value_type' not 'iterator_rangestring::iterator'
Sorry if I mis-understand what you teach me.
No worries.
There is no problem with using string_split::value_type. It is just a typedef to iterator_rangestring::iterator. In your code, you misplaced it with string_split itself.
I change the integer_compare class to use iterator_rangestring::iterator&.
And I am trying to loop thru the iterator_range inside the function() of integer_compare:
bool operator() (const iterator_rangestring::iterator& a,
const iterator_rangestring::iterator& b) { cout << "calling integer_compare " << endl;
// expect to print out "", "1", "1", "2" for a string of "/1/1/2" for (string::iterator sitr = a.begin(); sitr != a.end(); sitr++) {
cout << copy_rangestd::string(*sitr) << endl;
} return true; }
Please, see the iterator_range documentation: http://www.boost.org/libs/range/doc/utility_class.html#iter_range Although you changed the names of parameters, you are still using iterator_range as if it was a split_iterator. copy_range copies a *range* to a given container. when you dereference a string::iterator, you will not get a *range*, rather a single character. Instead of "for" loop you should use just cout << copy_rangestd::string(a) << endl; Regards, Pavol.
On 2/20/07, Pavol Droba
Hi,
Meryl Silverburgh wrote:
On 2/20/07, Pavol Droba
wrote: Pavol,
Thank for your help. I thought you said 'The question marks can be substituted by string_split::value_type'. In one of our previous exchange.
That is why I am using 'string_split::value_type' not 'iterator_rangestring::iterator'
Sorry if I mis-understand what you teach me.
No worries.
There is no problem with using string_split::value_type. It is just a typedef to iterator_rangestring::iterator. In your code, you misplaced it with string_split itself.
I change the integer_compare class to use iterator_rangestring::iterator&.
And I am trying to loop thru the iterator_range inside the function() of integer_compare:
bool operator() (const iterator_rangestring::iterator& a,
const iterator_rangestring::iterator& b) { cout << "calling integer_compare " << endl;
// expect to print out "", "1", "1", "2" for a string of "/1/1/2" for (string::iterator sitr = a.begin(); sitr != a.end(); sitr++) {
cout << copy_rangestd::string(*sitr) << endl;
} return true; }
Please, see the iterator_range documentation: http://www.boost.org/libs/range/doc/utility_class.html#iter_range
Although you changed the names of parameters, you are still using iterator_range as if it was a split_iterator.
copy_range copies a *range* to a given container. when you dereference a string::iterator, you will not get a *range*, rather a single character.
Instead of "for" loop you should use just cout << copy_rangestd::string(a) << endl;
Thanks, I did try just doing this
cout << copy_rangestd::string(a) << endl;
cout << copy_rangestd::string(b) << endl;
But I find out that 'integer_compare' just call once, and it is an empty string.
My input strings were "/1/11/2", "1/9/2". From your previous message,
I understand the first time return an empty string, but I do expect
integer_compare will call again and again like "1", "11", "2", "1",
"9" ,"2"....
But it did not happens.
class integer_compare {
public:
// bool operator() (const string_split::value_type &a, const
//string_split::value_type &b) {
bool operator() (const iterator_rangestring::iterator& a,
const iterator_rangestring::iterator& b) {
cout << "calling integer_compare " << endl;
cout << copy_rangestd::string(a) << endl;
cout << copy_rangestd::string(b) << endl;
/*
for (string::iterator sitr = a.begin(); sitr != a.end(); sitr++) {
cout << copy_rangestd::string(*sitr) << endl;
}*/
return true;
}
};
int main(int argc, char **argv) {
cout << "hello world" << endl;
string s1("/1/11/2");
string s2("/1/9/3");
iterator_range
Regards, Pavol. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Thanks, I did try just doing this cout << copy_rangestd::string(a) << endl; cout << copy_rangestd::string(b) << endl;
But I find out that 'integer_compare' just call once, and it is an empty string.
My input strings were "/1/11/2", "1/9/2". From your previous message, I understand the first time return an empty string, but I do expect integer_compare will call again and again like "1", "11", "2", "1", "9" ,"2".... But it did not happens.
Great, we are getting to the finish ;) There is just one slight problem, that I have overlooked in your code. lexicographical_compare simply forwards the call to std::lexicographical_compare http://www.sgi.com/tech/stl/lexicographical_compare.html So the given predicate (integer_compare) functions as *isless*. It means, that it should return true if the first argument is *less* then the second one. In case of equality it should return false. In your case, lexicographical_compare stopped on the first tokens, since the predicate reported that one is less then other. No other comparison was necessary to get the result. Try to change the result to false. You should be seeing the output from whole inputs. Best regards, Pavol.
On 2/20/07, Pavol Droba
Thanks, I did try just doing this cout << copy_rangestd::string(a) << endl; cout << copy_rangestd::string(b) << endl;
But I find out that 'integer_compare' just call once, and it is an empty string.
My input strings were "/1/11/2", "1/9/2". From your previous message, I understand the first time return an empty string, but I do expect integer_compare will call again and again like "1", "11", "2", "1", "9" ,"2".... But it did not happens.
Great, we are getting to the finish ;) There is just one slight problem, that I have overlooked in your code.
lexicographical_compare simply forwards the call to std::lexicographical_compare http://www.sgi.com/tech/stl/lexicographical_compare.html
So the given predicate (integer_compare) functions as *isless*. It means, that it should return true if the first argument is *less* then the second one. In case of equality it should return false.
In your case, lexicographical_compare stopped on the first tokens, since the predicate reported that one is less then other. No other comparison was necessary to get the result.
Try to change the result to false. You should be seeing the output from whole inputs.
Best regards, Pavol.
Pavol, Thank you very much for your effort/time/help. Yes, I do see the output. But still one question, why my function integer_compare is being call 2 times for every sub-string? my input strings are string s1("/1/11/2"), string s2("/1/9/3"); Here is my output: calling integer_compare () () calling integer_compare () () calling integer_compare (1) (1) calling integer_compare (1) (1) calling integer_compare (11) (9) calling integer_compare (9) (11) calling integer_compare (2) (3) calling integer_compare (3) (2)
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Meryl Silverburgh wrote:
On 2/20/07, Pavol Droba
wrote: Thanks, I did try just doing this cout << copy_rangestd::string(a) << endl; cout << copy_rangestd::string(b) << endl;
But I find out that 'integer_compare' just call once, and it is an empty string.
My input strings were "/1/11/2", "1/9/2". From your previous message, I understand the first time return an empty string, but I do expect integer_compare will call again and again like "1", "11", "2", "1", "9" ,"2".... But it did not happens.
Great, we are getting to the finish ;) There is just one slight problem, that I have overlooked in your code.
lexicographical_compare simply forwards the call to std::lexicographical_compare http://www.sgi.com/tech/stl/lexicographical_compare.html
So the given predicate (integer_compare) functions as *isless*. It means, that it should return true if the first argument is *less* then the second one. In case of equality it should return false.
In your case, lexicographical_compare stopped on the first tokens, since the predicate reported that one is less then other. No other comparison was necessary to get the result.
Try to change the result to false. You should be seeing the output from whole inputs.
Best regards, Pavol.
Pavol,
Thank you very much for your effort/time/help. Yes, I do see the output. But still one question, why my function integer_compare is being call 2 times for every sub-string?
my input strings are string s1("/1/11/2"), string s2("/1/9/3");
Here is my output:
calling integer_compare () () calling integer_compare () () calling integer_compare (1) (1) calling integer_compare (1) (1) calling integer_compare (11) (9) calling integer_compare (9) (11) calling integer_compare (2) (3) calling integer_compare (3) (2)
If you look better, you see that the arguments are reversed in the second call. because the interger_compare implements only '<' operation, we need actualy to call it twise to get ==. Anyway, if you find lexicographical_compare insufficient in some regards, I'm sure you can now implement version that suits your needs. Regards, Pavol.
On 2/20/07, Pavol Droba
Meryl Silverburgh wrote:
On 2/20/07, Pavol Droba
wrote: Thanks, I did try just doing this cout << copy_rangestd::string(a) << endl; cout << copy_rangestd::string(b) << endl;
But I find out that 'integer_compare' just call once, and it is an empty string.
My input strings were "/1/11/2", "1/9/2". From your previous message, I understand the first time return an empty string, but I do expect integer_compare will call again and again like "1", "11", "2", "1", "9" ,"2".... But it did not happens.
Great, we are getting to the finish ;) There is just one slight problem, that I have overlooked in your code.
lexicographical_compare simply forwards the call to std::lexicographical_compare http://www.sgi.com/tech/stl/lexicographical_compare.html
So the given predicate (integer_compare) functions as *isless*. It means, that it should return true if the first argument is *less* then the second one. In case of equality it should return false.
In your case, lexicographical_compare stopped on the first tokens, since the predicate reported that one is less then other. No other comparison was necessary to get the result.
Try to change the result to false. You should be seeing the output from whole inputs.
Best regards, Pavol.
Pavol,
Thank you very much for your effort/time/help. Yes, I do see the output. But still one question, why my function integer_compare is being call 2 times for every sub-string?
my input strings are string s1("/1/11/2"), string s2("/1/9/3");
Here is my output:
calling integer_compare () () calling integer_compare () () calling integer_compare (1) (1) calling integer_compare (1) (1) calling integer_compare (11) (9) calling integer_compare (9) (11) calling integer_compare (2) (3) calling integer_compare (3) (2)
If you look better, you see that the arguments are reversed in the second call. because the interger_compare implements only '<' operation, we need actualy to call it twise to get ==.
Anyway, if you find lexicographical_compare insufficient in some regards, I'm sure you can now implement version that suits your needs.
I guess a bigger problem for me for using lexicographical_compare is I will get opposite result depends on the order of the input string: For example, if I have string s1("/1/9"), string s2("/1/9/3"); the compare will return true, but if I have string s1("/1/9/3"), string s2("/1/9"); it will return false. But for my case, I always want "/1/9" less than "/1/9/3" I guess I can compare the length of the 2 string and always put s1 to be the shorter one, and s2 to be the longer one. if there is an more efficient/cleaner idea, please let me know.
Regards, Pavol. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Meryl Silverburgh wrote: <snip>
I guess a bigger problem for me for using lexicographical_compare is I will get opposite result depends on the order of the input string: For example, if I have string s1("/1/9"), string s2("/1/9/3");
the compare will return true,
but if I have
string s1("/1/9/3"), string s2("/1/9");
it will return false.
But for my case, I always want "/1/9" less than "/1/9/3"
I guess I can compare the length of the 2 string and always put s1 to be the shorter one, and s2 to be the longer one.
if there is an more efficient/cleaner idea, please let me know.
Here is an excert from the lexicographica_compare documentation in msdn: <quote> A lexicographical comparison between sequences compares them element by element until: It finds two corresponding elements unequal, and the result of their comparison is taken as the result of the comparison between sequences. No inequalities are found, but one sequence has more elements than the other, and the shorter sequence is considered less than the longer sequence. No inequalities are found and the sequences have the same number of elements, and so the sequences are equal and the result of the comparison is false. </quote> So the lexicographical_compare does indeed take the lenght of sequences into account. The problem you see, is due to the nature it handles you the result. If lexc(a,b) returns true, you know that a
participants (2)
-
Meryl Silverburgh
-
Pavol Droba