|
-
June 7th, 2008, 07:30 PM
#1
STL string gurus - please help!
I wish to replace a set of substrings in a string. I have experimented with various methods to do this. I thought I had it working, but no... under certain circumstances that I do not understand but can readily reproduce, my code encounters a runtime error with the message: 'the string iterator is not dereferencable'.
Here's the code I have been trying to develop:
Code:
int count;
char buf[256];
double x[7];
string s, so, sr;
string::iterator tt;
vector<string> vs1, vs2;
x[0] = 1.123234345;
x[1] = 2.293849223;
x[2] = 3.283746834;
x[3] = 4.758439842;
x[4] = 5.234543234;
x[5] = 6.728394823;
x[6] = 7.923874943;
s = "t = %0.8f\nu = %0.8f\nv = %0.8f\nw = %0.8f\nx = %0.8f\ny = %0.8f\nz = %0.8f\n";
cout << s << endl;
so = "%0.8f";
tt = s.begin();
count = 0;
while(tt != s.end())
{
if(*tt == '%')
{
sprintf(buf, "%0.4f", x[count]);
//sprintf(buf, "%0.5f", x[count]); // error: string iterator not dereferencable
sr = string(buf);
s.replace(tt, tt + so.size(), sr);
count++;
}
*tt++;
}
cout << s << endl;
Now, at first glance, I thought I understood the problem, that is, I thought that the replacement string cannot be longer than the substring one wishes to replace. Thus, so = "%0.8f"; has 5 characters (plus '\0'), so that using a 6 or greater length string will cause the replace function iterator to fail.
But further experimentation shows that this is probably NOT the problem. For example, this code works without a problam
Code:
size_t n;
string s, so, sr;
string::iterator tt;
s = "x = %0.8f";
so = "%0.8f";
sr = "123233453454.345445645645656567";
cout << s << endl;
n = s.find('%', 0);
tt = s.begin() + n;
s.replace(tt, tt + so.size(), sr);
cout << s << endl;
// output: x = 123233453454.345445645645656567
Frankly, I am at a loss to know what's happening here. Any of your ideas would certainly be appreciated. Thanks.
Mike
mpliam
-
June 7th, 2008, 11:58 PM
#2
Re: STL string gurus - please help!
-
June 8th, 2008, 01:41 AM
#3
Re: STL string gurus - please help!
the iterator "tt" is invalidated by replace()
-
June 8th, 2008, 10:34 AM
#4
Re: STL string gurus - please help!
I think you are going about it the hard way, plus you are using C functions like scanf(), which don't help.
Here's how to do it with standard streams and iterators.
Method One is just building the string (no replacing involved).
Method Two is essentially a string replace in that it only copies the stuff it wants out of the source string...
Code:
#include <algorithm> // copy()
#include <iomanip> // setprecision()
#include <iostream>
#include <iterator> // back_insert_iterator<>
#include <sstream>
#include <string>
using namespace std;
//----------------------------------------------------------
string method_one( double x[7] )
//
// Build the result string from scratch
{
char names[] = "tuvwxyz";
stringstream result;
for (int i = 0; i < 7; i++)
result << names[i] << " = " << fixed << setprecision( 4 ) << x[i] << endl;
return result.str();
}
//----------------------------------------------------------
string method_two( const string& s, const string& subs, double x[] )
//
// Build the result string by replacing stuff in 's'
{
string result;
string::const_iterator nexti, i = s.begin();
back_insert_iterator <string> ri( result );
for (int n = 0; true; n++)
{
// Find the next matching substring
nexti = search( i, s.end(), subs.begin(), subs.end() );
if (nexti == s.end()) break;
// Copy everything before the matching part
copy( i, nexti, ri );
// Convert x to string and add it instead of the matching part of s
stringstream ss;
ss << fixed << setprecision( 4 ) << x[n];
string t = ss.str();
copy( t.begin(), t.end(), ri );
i = nexti +subs.length();
}
// Copy any remaining part
copy( i, s.end(), ri );
return result;
}
//----------------------------------------------------------
int main()
{
double x[7] = {
1.123234345,
2.293849223,
3.283746834,
4.758439842,
5.234543234,
6.728394823,
7.923874943
};
cout << "method one: \"" << method_one( x ) << "\"\n";
cout << "method two: \"" << method_two(
"t = %0.8f\nu = %0.8f\nv = %0.8f\nw = %0.8f\nx = %0.8f\ny = %0.8f\nz = %0.8f\n",
"%0.8f",
x
) << "\"\n";
return 0;
}
Doing an actual replace is not that hard either, but that's where you'll hit the limitations of the STL's iterator capabilities... (hopefully C++0x fill fix some of those flaws).
Hope this helps.
-
June 8th, 2008, 11:38 AM
#5
Re: STL string gurus - please help!
Thank you so very much for your kind help.
Do you think that the problem I have encountered with 'release' represents a coding error on my part or a bug in the STL ?
Mike
mpliam
-
June 8th, 2008, 11:54 AM
#6
Re: STL string gurus - please help!
coding error on your part
Wakeup in the morning and kick the day in the teeth!! Or something like that.
"i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."
-
June 8th, 2008, 02:21 PM
#7
Re: STL string gurus - please help!
Yes, it is exactly as spoon! said: all iterators into a container are invalidated whenever you use insert() or replace(), etc.
The probability of new programmers and even very experienced folk such as myself finding a bug in the STL is close enough to zero that we might as well consider it as "can't happen." Leave that kind of stuff to the STL committee experts.
Hope this helps.
-
June 8th, 2008, 02:54 PM
#8
Re: STL string gurus - please help!
 Originally Posted by Duoas
all iterators into a container are invalidated whenever you use insert() or replace(), etc.
That depends on the container.
Wakeup in the morning and kick the day in the teeth!! Or something like that.
"i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."
-
June 10th, 2008, 08:30 PM
#9
Re: STL string gurus - please help!
According to Herb Schildt (C++, The Complete Reference), strstream is deprecated, even though it is still supported by most compilers because it is so widely used. Visual Studio gives no indication that strstream is deprecated. Is it OK to continue to use it, or is there some more uptodate alternative ?
Mike
mpliam
-
June 10th, 2008, 08:50 PM
#10
Re: STL string gurus - please help!
Wakeup in the morning and kick the day in the teeth!! Or something like that.
"i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."
-
June 11th, 2008, 02:18 PM
#11
Re: STL string gurus - please help!
Good reference. stringstream is still OK. Schildt was referring to strstream. I need to read things more carefully. Thanks.
Last edited by Mike Pliam; June 11th, 2008 at 02:21 PM.
Reason: error
mpliam
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|