I am having problem with programming, i have been given a program to perfom and so far i have benn unable to start..can anyone help me? This is my question..1. Create a class called MyString. Within this class, you are to implement, from scratch, two versions of each of the string concat functions (strcat, strncat) and string comparison functions (strcmp, strncmp) functions discussed in class. This does not mean using the existing functions strcpy, strncpy etc. that have already been written and implemented in the <cstring> class. Instead, it means you are responsible for writing each of these functions as if they never existed. You are then to build a driver program that constructs a MyString object and then uses it to execute each of the functions you wrote. Since there are two versions of each function that you will build, make sure that one version is done using array subscripting and the second uses pointers and pointer arithmetic. Array subscripting means that you will treat everything in your code like an array (use brackets instead of the asterisk) whereas pointer arithmetic means everything will be treated as a pointer (you will use the asterisk instead of array brackets). You should have a total of 8 functions.

Recommended Answers

All 9 Replies

First show some work. Then we'll help you with specific problems.

The two groups of functions you are aske to replicate are really pretty simple. Your biggest task is to actually instantiate the strings.

So, understand what the various functions/processes need to do (RTFM), and then write out how you would, in simple words, how you would go about performing those processes - this is called "pseudo code". Then consider how you would do that in a C++ class-based environment where strings have their own class. IE, the signature for strcat(target, source), may be something like this:

MyString& MyString::strcat(const MyString& source)
{
    ::strcat(this->raw_string, source.raw_string);
    return *this;
}

Of course, you will also need to add code to increase the size of the local raw_string variable as necessary. This is just one example, and not a particularly great one - I wouldn't use it for production code!

we build a function print hyphen bt i want after every 5 hyphen next hyphen write on the new line and so on...
how can i achieve this??

Hassan, you need to try to solve the problem, then post your code here with descriptions (and output) of errors that you are getting, then we may be able to help you. We DO NOT do your homework for you!

Haven't we been here before? Oh, yeah, we have. In that case, let me repeat what I said last time:

First off, don't hijack other people's threads with unrelated questions; if you have a new question not related to the thread, create a new thread.

Second, didn't you read what I said to the OP? We don't do other people's homework for them like that. If you want help, show us what you've already done, otherwise, we can't help you and won't even respond to you. If you want the work done for you, hie your lazy self to freelancer.com and pay someone to do it, just don't cry to us when you get caught cheating.

Okay,. am sorry,  am new to this website but i really need help with my work i have started to buil my code..so far i have this..it those compile but am not sure if am going the right way.
#include "mystring.h"
#include <cstring>

char *stringStr( char *str1, char *str2[] );

int main()
{
string str1 = "C++ language";
string str2   = "is the best ";

MyString stringobject(str1,str2);

stringobject.print();

stringobject.insert();

cin.get();
 cin.get();
return 0;
}

**".h"**
#ifndef MYSTRING_H
#define MYSTRING_H

#include <iostream>
using namespace std;

class MyString
{
public:
    MyString(string,string);
    void setstring1(string);
    void setstring2(string);
    string getstring1();
    string getstring2();
    void print();
    void insert();
private:
    string str1;
    string str2;
};

#endif // MYSTRING_H
**"CPP"**
#include "mystring.h"


MyString::MyString(string num1,string num2)
{
    setstring1(num1);
    setstring2(num2);
}

void MyString::setstring1(string num1)
{
    str1=num1;
}

void MyString::setstring2(string num1)
{
    str2=num1;
}

string MyString::getstring1()
{
    return str1;
}

string MyString::getstring2()
{
    return str2;
}

void MyString::print()
{
    // insert a copy of str2 into str1
    // at position pos;
    cout << "\n\nbefore\n\n";
    cout << "str1 is: " << str1 << endl;
    cout << "str2 is: " << str2 << endl;
    cout << "\n\nAfter\n\n";
}

void MyString::insert()
{

    int pos = 4;
    str1.insert(pos,str2);
    cout << "str1 is: " << str1 << endl;

    // like above but n x copies of char
    str1.insert(str1.end(),4,'!');
    cout << "str2 is: " << str1 << endl;

    // insert range (begin - begin+4) of str1
    // into str2 at position begin+3
    str2.insert(str2.begin()+3,str1.begin(),str1.begin()+4);
    cout << "str3 is: " << str2 <<"?"<< endl;
}

Do you already have a string class to work with?

If NOT, you seem to be off on the wrong track ... ?

A common student problem is to build ... bottom up ... a class String ...

perhaps using a (dynamically allocated) C char string inside ...
(a 0 terminated block of char's as the private data member of the class String)

... and in your case, this class String is also to implement:

2 versions of strncat
2 versions of strcat
2 versiona of strncpy
2 versions of strcpy

?

If you were do some Google searching, you could find several examples of a C++ String class, to give you some ideas ... to help you get started on the right track.

Take a look at this 'shell' ... just a start ...

examples

// test_newBase_String.cpp //  // 2014-03-12 //

 /* *** This may? give you some idea how to start ***


    http://www.4shared.com/folder/xPqGQHPl/class_String.html


    two versions of each of the string concat functions 
    (strcat, strncat) 

    and string comparison functions 
    (strcmp, strncmp)

    Since there are two versions of each function that you will build, 
    make sure that one version is done using array subscripting 
    and the second uses pointers and pointer arithmetic. 

    Array subscripting means that you will treat everything in your code 
    like an array (use brackets instead of the asterisk) 

    whereas pointer arithmetic means everything will be treated as a pointer 
    (you will use the asterisk instead of array brackets). 

    You should have a total of 8 functions.
*/

#ifndef BASE_STRING_H
#define BASE_STRING_H

#include <iostream>
//#include <cstring> // re. strlen  // but now using private member buflen


class Base_String
{
public:
    Base_String(); // default ctor ... empty string, null terminated, length 0
    Base_String( const char* ); // ctor with a passed in C string ... "" is ok
    Base_String( char ); // ctor with a passed in character ... NOT ''
    Base_String( size_t ); // ctor of n+1 bytes to hold a string up to (n bytes + 0 terminator)

    Base_String( const Base_String& ); // copy ctor ...
    Base_String ( char, size_t ); // ctor ... to create/initial a Base_String with a repeated char

    ~Base_String(); // dtor ...

    void clear();

    void reserve( size_t n );
    void resize( size_t n );

    Base_String& operator= ( const Base_String& ); // overloaded assignment operator=
    Base_String& operator= ( const char* ); // get a new Base_String copy of C string passed in

    char& operator[] (size_t); // returns the char at valid index int
    const char& operator[] ( size_t ) const ;

    size_t size() const { return len; } // Note: inline ...
    size_t capacity() const { return cap; }

    // extract and return the substring of a String object starting at
    // a particular index in the buffer and of a specified length.
    // if numChars is too large ... just the rest of the string is copied
    Base_String substr( size_t startIndex, size_t numChars ) const ;

    Base_String substr( size_t startIndex ) const ;

    int find_index( char charToFind ) ;
    int find_index( const Base_String& strToFind ) ;

    Base_String& strncat( const Base_String& ms, size_t n );
    Base_String& strncat( const char* s, size_t n );

    Base_String& strcat( const Base_String& ms );
    Base_String& strcat( const char* s );

    Base_String& strncpy( const Base_String& ms, size_t n );
    Base_String& strncpy( const char* s, size_t n );

    Base_String& strcpy( const Base_String& ms );
    Base_String& strcpy( const char* s );

    // ...

protected:
    size_t len;
    size_t cap; // capacity
    char* buf;

    size_t buflen( const char* );

    friend std::ostream& operator << ( std::ostream&, const Base_String& );

    /* NOTE! this version of fin >> ... 
       eats the 1st ws after end of NON ws chars */
    friend std::istream& operator >> ( std::istream&, Base_String& );
    friend std::istream& getline( std::istream&, Base_String&, 
                                    const Base_String& d = '\n' ); 
} ;

namespace my
{
    const char* delimits = " \n\t";
    size_t start_buf_size = 128;

    // Note: in own namespace ... so call with ... my :: 
    void waitForEnter( const char* msg )
    {
        std::cout << msg << std::flush;

        // 'flush' cin until 'eat' char '\n'
        while( std::cin.get() != '\n' ) ;
    }

    bool char_is_in( char c, const char* s )
    {
        while( *s ) // while( *s != 0 )
            if( c == *s++ ) return true;
        // else ... if reach here ...
        return false;
    }
}

#endif



// three friend functions defined ...

std::ostream& operator << ( std::ostream& os, const Base_String& s )
{
    return os << s.buf;
}

// .......


int Base_String::find_index( char charToFind ) // returns index or -1;
{
    for( int i = len-1; i >= 0; --i )
        if( buf[i] == charToFind ) return i;
    // if reach here ...
    return -1;
}

// returns index or -1 ... case specific
int Base_String::find_index( const Base_String& strToFind )
{
    char* cur = this->buf;
    char* cursave;
    char* front = strToFind.buf;

    while( *cur != 0 ) // i.e. while not at null at end ...
    {
        if( *cur !=0 && *cur != *front )
        {
            cur++;
        }
        else // first char's match ... so check the next char's in ...
        {
            cursave = cur; // get a copy ...

            while(*cur !=0 && *front != 0 && *cur == *front)
            {
                cur++;
                front++;
            }
            if(*front == 0) // we have a match ... so ...
                return (int)(cursave - this->buf); // return index ...

            // If reach here ... no match above so try again ... till at end
            cur = cursave +1;
            front = strToFind.buf;
        }
    }

    // if reach here ...
    return -1; // since no match above ...
}


// .......

Base_String& Base_String::strncat( const Base_String& ms, size_t n )
{
    size_t i, nlen = len + n;

    if( cap < nlen ) reserve( nlen );

    for( i = 0; i <= n; ++i ) // <= to copy 0 at end ....
        buf[len+i] = ms.buf[i];

    //buf[i] = 0; // done above
    len = nlen;
    return *this;
}

Base_String& Base_String::strncat( const char* s, size_t n )
{
    size_t nlen = len + n;

    if( cap < nlen ) reserve( nlen );

    char* p = buf;

    p = p+len;
    while( *s ) // can NOT use p here !!! //
    {
        *p = *s;
        ++p, ++s;
    }

    *p = 0; // 0 terminate if str's are 0 terminated
    len = nlen; 

    return *this;
} 





// a tiny test program ...
int main()
{
    using std::cout; using std::endl; using std::flush; 
    using std::cin;  

    Base_String n1( "Joe" ), n3( "Moe" );
    cout << n1 << ' ' << n3 <<  endl;

    n1.strncat( " Curley ", 8 );

    cout << "n1 = " << n1
         << ", n1.size() = " << n1.size()
         << ", n1.capacity() = " << n1.capacity()
         << endl;


    n1.strncat( n3, n3.size() );

    cout << "n1 = " << n1
         << ", n1.size() = " << n1.size()
         << ", n1.capacity() = " << n1.capacity()
         << endl;;

    cout << "Enter a word: " << flush;
    cin >> n1;

    cout << "\n   n1.size() = " << n1.size() << ", " 
         << "n1.capacity() = " << n1.capacity() << ", " 
         << n1 << endl;


    cout << "Enter a sentence: " << flush;
    getline( cin, n1 );

    cout << "\n   n1.size() = " << n1.size() << ", " 
         << "n1.capacity() = " << n1.capacity() << ", " 
         << n1 << endl;
}
okay,. so far am to this point,. i have managed to do a version of strcat which include a 
array and a pointer,. but i still have problems with the other function..

#include <iostream>
using namespace std;

class MyString
{
public:
    MyString();
    //void printArray();
    char *  insertArray(char str1[], char str2[]);

    //void printPointer();
    //void insertPointer();

private:


};
\\\\\\\\\\\\\\\\\

#include <iostream>
using namespace std;

#include "mystring.h"

char *stringStr( char *str1[], char *str2[]);

int main()
{
    char str1[70] = "c++ language";
    char str2[70] = "is the best ";
    MyString stringobject;
    cout<<str1<<endl;
    cout<<str2<<endl;
    cout<<stringobject.insertArray(str1,str2)<<endl;

    cout<<endl;

    char str3[70] = "c++ language ";
    char str4[70] = "is the best ";
    MyString stringobject2;
    cout<<str3<<endl;
    cout<<str4<<endl;
    cout<<stringobject2.insertArray(str3,str4)<<endl;



    cin.get();
    cin.get();

    return 0;
}

\\\\\\\\\\\\\\\\

#include "mystring.h"

#include <cstring>

#include <iomanip>
using std::setw;

MyString::MyString()
{

}

char *  MyString::insertArray( char str1[], char str2[])
{
    int firstloop=0;

    for(;str1[firstloop]!='\0';firstloop++)
    {
    }

    int secondloop=0;

    for(;str2[secondloop]!='\0';secondloop++,firstloop++)
    {
        str1[firstloop]=str2[secondloop];
    }
    str1[firstloop]='\0';
    return str1;
}

char *  MyString::insertArray2( char * str1, char * str2)
{
    int firstloop=4;

    for(;*(str1+firstloop)!='\0';firstloop++)
    {
    }

    int secondloop=0;

    for(;*(str2+secondloop)!='\0';secondloop++,firstloop++)
    {
        *(str1+firstloop)=*(str2+secondloop);
    }
    *(str1+firstloop)='\0';
    return str1;
}

Very creative ... :)

-> using pre-fixed length C strings ... (Not a good idea usually...in designing a C++ string class ?)

-> some curious stuff ... that I am surprized that you even got compiled and then to have any good output ?

BUT ... please turn on your COMPILER error warnings ... so you can see what to fix ... and then ... look at the example below ... and see all the embedded comments ... to see the way a typical student class String ... is (normally) expected to look ...

// student_classString.cpp //

/*
    okay,. so far am to this point,. 
    i have managed to do a version of strcat which include a 
    array and a pointer,. 
    but i still have problems with the other function..
*/

/*
    Ok ... you seem to be needing a little nudge in the
    'right direction' ... to get started
    please lookup or Google 'the big 3 of C++ classes' ... 
*/


#include <iostream>
#include <cstring> // re. strlen

using namespace std;


class MyString
{
public:
    MyString();
    ~MyString(); // 1... of 'BIG THREE' ... needed here

    // copy ctro...
    MyString( const MyString& ); // 2... of 'BIG THREE' ...

    // ALSO, need to have ...
    // ctor from passed in C string ... 
    // (so can construct fron C strings)
    MyString( const char[] );

    // overloaded assignment ...
    MyString& operator = ( const MyString& ); // 3... of 'BIG THREE' ...

    MyString& concat( const char[] );
    MyString& concat( const MyString& );

    size_t size() const { return len; } // Note: inline here ...
    size_t capacity() const { return cap; } // ... inline

private:
    // where are your private data member 
    // to hold the data in the string ?
    // these 3 are COMMON ...

    size_t len; // length
    size_t cap; // capacity
    char* data;

    friend ostream& operator << ( ostream&, const MyString& );
} ;



// friend def'n ...
ostream& operator << ( ostream& os, const MyString& out )
{
    return os << out.data; // C++ 'knows' how to use << for C string obj's  
}

// member definitions ...

// default ctor ..
MyString::MyString() // construct and empty 0 terminated String
{
    len = cap = 0;
    data = new char [1];
    data[0] = 0;
}
// destructor ...
MyString::~MyString()
{
    delete [] data;
    len = cap = 0;
}

// copy ctor...
MyString::MyString( const MyString& in ) // 2... of 'BIG THREE' ..
{
    len = in.len;
    cap = in.cap;
    data = new char[cap+1];
    // copy terminating 0 also ...
    for( size_t i = 0; i <= len; ++ i ) data[i] = in.data[i];
}
// ctor from passed in C string ... 
//(so can construct fron C strings)
MyString::MyString( const char in[] )
{
    len = strlen(in);
    cap = len;
    data = new char[cap+1];
    // copy terminating 0 also ...
    for( size_t i = 0; i <= len; ++ i ) data[i] = in[i];

}

// overloaded assignment ...
MyString& MyString::operator = ( const MyString& in ) // 3... of 'BIG THREE'
{
    if( this != & in )
    {
        len = in.len;
        cap = in.cap;
        data = new char[cap+1];
        // copy terminating 0 also ...
        for( size_t i = 0; i <= len; ++ i ) data[i] = in.data[i];
    }
    return *this;  //  Note: using the 'this pointer' is THE way to access
                  // the address to the C++ class object    
}

// ok ... NOW can deal with this ... (if you wish to def'n the concat's first)
MyString& MyString::concat( const char in[] )
{
    size_t inlen = strlen(in);
    if( cap < len + inlen )
    {
        cap = len + inlen;
        char* tmp = new char[cap+1];
        // copy over to tmp ...
        for( size_t i = 0; i < len; ++ i ) tmp[i] = data[i];
        // now can ...
        delete [] data;
        // and ... update address ...
        data = tmp;
    }
    // now can concat ... and copy ) at end !
    for( size_t i = 0; i <= inlen; ++ i ) data[len+i] = in[i];

    // now can assign new len ...
    len = len + inlen;

    return *this;
}
MyString& MyString::concat( const MyString& in )
{
    if( cap < len + in.len )
    {
        cap = len + in.len;
        char* tmp = new char[cap+1];
        // copy over to tmp ...
        for( size_t i = 0; i < len; ++ i ) tmp[i] = data[i];
        // now can ...
        delete [] data;
        // and ... update address ...
        data = tmp;
    }
    // now can concat ... and copy ) at end !
    for( size_t i = 0; i <= in.len; ++ i ) data[len+i] = in.data[i];

    // now can assign new len ...
    len = len + in.len;

    return *this;
}



int main()
{
    const char str1[] = "C++ language";
    const char str2[] = "is the best";

    MyString s1( str1 ), s2( str2 );

    cout << "s1 = '" << s1 << "'" << endl;
    cout << "s2 = '" << s2 << "'" << endl;

    s1.concat( " " );
    cout << "s1.concat( \" \" ) = '" << s1.concat( " " ) << "'" << endl;

    cout << "s1.concat( s2 ) = '" << s1.concat( s2 ) << "'" << endl;

    cout << "s1.concat( \"!\" ) = '" << s1.concat( "!" ) << "'" << endl;


    cout << "\nPress 'Enter' to continue/exit ... " 
         << flush; // NOT usually necessary ... but I lilke to show/ensure 'flush'

    cin.get();

    return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.