Valhalla Legends Forums Archive | C/C++ Programming | C++ can do anything!

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

[code]
#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;
}
[/code]
November 21, 2003, 12:01 AM
Eibro
Did this awhile back, it was a really neat project :D
[code]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;[/code]
November 21, 2003, 12:28 AM
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 :)
November 21, 2003, 12:51 AM

Search