• Welcome to Valhalla Legends Archive.
 

C++ can do anything!

Started by Zakath, November 20, 2003, 06:01 PM

Previous topic - Next topic

Zakath

As an example, I've duplicated the functionality of the VB Mid function and statement. The error-checking is a little weak since I didn't spend a ton of time on it, but it works perfectly when all input is valid.


#include "stdlib.h"
#include "stdio.h"
#include "string.h"

class string_wrapper;

string_wrapper Mid( const char *, int, int = -1 );
string_wrapper Mid( char *, int, int = -1 );

class string_wrapper {
public:
   string_wrapper( char * );
   string_wrapper( const string_wrapper &);
   ~string_wrapper();
   operator char *();
   string_wrapper &operator =(char *);
   string_wrapper &operator =(const string_wrapper &);
   void set_start( const unsigned int );
   void set_replacelen( const int );
   //not normally used
   void set_replaceptr( char * );
private:
   char *string;
   unsigned int replacestart;
   int replacelen;
   char *replaceptr;
};

void string_wrapper::set_replaceptr( char *strptr ) {
   replaceptr = strptr;
}

void string_wrapper::set_start( const unsigned int n ) {
   replacestart = n;
}

void string_wrapper::set_replacelen( const int i ) {
   replacelen = i;
}

string_wrapper::string_wrapper( char *initstring ) {
   if ( initstring == NULL )
      string = NULL;
   else {
      int len = strlen( initstring );
      string = new char[ len + 1 ];
      strcpy( string, initstring );
      string[ len ] = '\0';
   }
   replacestart = 0;
   replacelen = -1;
   replaceptr = NULL;
}

string_wrapper::string_wrapper(const string_wrapper &target) {
   if ( target.string == NULL )
      string = NULL;
   else {
      int len = strlen( target.string );
      string = new char[ len + 1 ];
      strcpy( string, target.string );
      string[ len ] = '\0';
   }
   replacestart = target.replacestart;
   replacelen = target.replacelen;
   replaceptr = target.replaceptr;
}

string_wrapper::~string_wrapper() {
   if ( string != NULL )
      delete [] string;
}

string_wrapper::operator char *() {
   return string;
}

string_wrapper &string_wrapper::operator =(const string_wrapper &target) {
   operator =( target.string );
   return *this;
}

string_wrapper &string_wrapper::operator =(char * newstr) {
   if ( newstr == NULL ) {
      if ( string != NULL )
         delete [] string;
      string = NULL;
   }
   else {
      if ( !replacestart ) {
         if ( string != NULL )
            delete [] string;
         string = new char[ strlen( newstr ) + 1 ];
         strcpy( string, newstr );
      }
      else {
         int len, targetlen;
         len = strlen( replaceptr );
         targetlen = strlen( newstr );
         if ( replacelen > targetlen )
            replacelen = targetlen;
         char *tmp = new char[ len + 1 ];
         strncpy( tmp, replaceptr, (replacestart - 1) );
         tmp[ replacestart - 1 ] = '\0';
         if ( replacelen == -1 )
            strncat( tmp, newstr, (len - replacestart + 1) );
         else {
            strncat( tmp, newstr, replacelen );
            strcat( tmp, (replaceptr + replacestart - 1 + replacelen ) );
         }
         tmp[ len ] = '\0';
         strcpy( replaceptr, tmp );
         strncpy( string, newstr, replacelen );
         delete [] tmp;
      }
   }
   replaceptr = NULL;
   replacestart = 0;
   replacelen = -1;
   return *this;
}

int main( int argc, char **argv ) { //Note the declaration of main
   //This demonstrates the use of Mid

   printf( "%s\n", (char *)Mid( "The middle of a string", 5, 6 ));
   //It requires a cast when the type is not explicit

   char str[] = "I'll replace \"bleh\" with \"test\"";
   Mid( str, 15, 4 ) = Mid( str, 1, 4 ) = "test";
   printf( "%s\n", str );

   return 0;
}

//Mid function
string_wrapper Mid( const char *lpszStr, int nStart, int nLength ) {
   if ( (nStart - 1) > strlen( lpszStr ) || nStart < 0 || nLength < 0 ) {
      string_wrapper blah1( "" );
      return blah1;
   }
   else {
   int newlen;
   if ( nLength == -1 )
      newlen = strlen( lpszStr ) - nStart + 1;
   else {
      if ( nLength > strlen( (lpszStr + nStart - 1) ) )
         newlen = strlen( lpszStr ) - nStart + 1;
      else newlen = nLength;
   }
   char *tmp = new char[ newlen + 1 ];
   strncpy( tmp, (lpszStr + nStart - 1), newlen );
   tmp[ newlen ] = '\0';
   string_wrapper blah( tmp );
   delete [] tmp;
   return blah;
   }
}

//Mid statement
string_wrapper Mid( char *lpszStr, int nStart, int nLength ) {
   if ( (nStart - 1) > strlen( lpszStr ) || nStart < 0 || nLength < 0 ) {
      string_wrapper blah1( "" );
      return blah1;
   }
   int newlen;
   if ( nLength == -1 )
      newlen = strlen( lpszStr ) - nStart + 1;
   else {
      if ( nLength > strlen( (lpszStr + nStart - 1) ) )
         newlen = strlen( lpszStr ) - nStart + 1;
      else newlen = nLength;
   }
   char *tmp = new char[ newlen + 1 ];
   strncpy( tmp, (lpszStr + nStart - 1), newlen );
   tmp[ newlen ] = '\0';
   string_wrapper blah( tmp );
   delete [] tmp;
   blah.set_start( nStart );
   blah.set_replacelen( nLength );
   blah.set_replaceptr( lpszStr );
   return blah;
}
Quote from: iago on February 02, 2005, 03:07 PM
Yes, you can't have everybody...contributing to the main source repository.  That would be stupid and create chaos.

Opensource projects...would be dumb.

Eibro

Did this awhile back, it was a really neat project :D
class CLASS_MID
{
public:

   CLASS_MID() : off(0)
   {  
       m_position[0] = m_position[1] = 0;
       m_length[0] = m_length[1] = 0;
   };

   CLASS_MID& operator() (std::string& str, unsigned int pos, unsigned int len)
   {
       if (pos >= str.length())
           pos = str.length();

       if (len > str.length())
           len = str.length();

       ++off;
       off &= 1;
       
       m_position[off] = pos;
       m_length[off] = len;
       m_string[off] = &str;
       
       return *this;
   }

   CLASS_MID& operator=(std::string& str)
   {
       std::string before = m_string[off]->substr(0, m_position[off]);
       std::string after = m_string[off]->substr(m_length[off] + m_position[off],
           m_string[off]->size() - m_length[off] - m_position[off]);
       
       *m_string[off] = before + str + after;
       return *this;
   }

   CLASS_MID& operator=(CLASS_MID& rhs)
   {
       int rhsoff = (off == 0);
       // Inverse of off (offset of current strings and positions)
       // if we're assigning to another CLASS_MID, then
       // the other slot in our arrays must be filled

       std::string before = m_string[off]->substr(0, m_position[off]);
       std::string after = m_string[off]->substr(m_length[off] +
           m_position[off], m_string[off]->size() -
           m_length[off] - m_position[off]);

       *m_string[off] = before + std::string(rhs.m_string[rhsoff]->begin() +
           rhs.m_position[rhsoff], rhs.m_string[rhsoff]->begin() +
           rhs.m_position[rhsoff] + rhs.m_length[rhsoff]) + after;

       return *this;
   }


   operator std::string ()
   {
       return m_string[off]->substr(m_position[off], m_position[off]+m_length[off]);
   }

   operator const char* ()
   {
       return m_string[off]->substr(m_position[off], m_position[off]+m_length[off]).c_str();
   }


private:

   CLASS_MID(const CLASS_MID& rhs);

   std::string* m_string[2];
   unsigned int m_position[2];
   unsigned int m_length[2];

   int off;

} Mid;
Eibro of Yeti Lovers.

Adron

U r so 0wnage :P


And as a side-note, Zakath was a non-believer at first. But now that the faith is with him, C++ can do anything in his hands. Good job Zakath :)