CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    May 2002
    Posts
    1,798

    Smile 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

  2. #2
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,244

    Re: STL string gurus - please help!

    [ Moved thread ]

  3. #3
    Join Date
    Dec 2006
    Posts
    166

    Re: STL string gurus - please help!

    the iterator "tt" is invalidated by replace()

  4. #4
    Join Date
    May 2008
    Posts
    96

    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.

  5. #5
    Join Date
    May 2002
    Posts
    1,798

    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

  6. #6
    Join Date
    Nov 2002
    Location
    Los Angeles, California
    Posts
    3,863

    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."

  7. #7
    Join Date
    May 2008
    Posts
    96

    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.

  8. #8
    Join Date
    Nov 2002
    Location
    Los Angeles, California
    Posts
    3,863

    Re: STL string gurus - please help!

    Quote 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."

  9. #9
    Join Date
    May 2002
    Posts
    1,798

    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

  10. #10
    Join Date
    Nov 2002
    Location
    Los Angeles, California
    Posts
    3,863

    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."

  11. #11
    Join Date
    May 2002
    Posts
    1,798

    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
  •  





Click Here to Expand Forum to Full Width

Featured