Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Java-like String object
Index -> Programming, C++ -> C++ Tutorials
View previous topic Printable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
rizzix




PostPosted: Thu Sep 04, 2003 4:42 pm   Post subject: Java-like String object

here's something useful, a java.lang.String object that you can use.
some things to remember while using this class.

1] any method that returns a String& reference, is basically returning a new object, so you'll have to delete it when not necessary

2] to print the string to terminal do this: cout << str.toString() << endl;

3] the toCharArray will return a pointer to a new char array, so delete it when you have no use of it.

4] the string object is immutable, all methods are const

5] basic primitive types are returned by value

6] the only methods that return a pointer to String object are the 2 substring methods, because it returns null if error

7] all methods returning an int or char, return -1 if error.

8] the indexOf methods that take a String or char* as an argument are NOT IMPLEMENTED

now here's the code...
code:

/***************************************************************************
      string.h  -  A C++ version of java.lang.String with added features
                             -------------------
    begin                : Sun Aug 31 2003
    copyright            : (C) 2003 by rizzix
    email                : rizzixs@fastmail.fm
 ***************************************************************************/

#ifndef RIZZIX_STRING_H
#define RIZZIX_STRING_H

/**
  *@author rizzix
  */

class String {
private:
    int len;
    char* str;
public:
    String();
    String(const String& pstr);
    String(const char* const pstr);
    virtual ~String();

    int length() const;
    const char* const toString() const;
    String& concat(const String& pstr) const;
    String& concat(const char* const pstr) const;
   
    bool endsWith(const String& str) const;
    bool endsWith(const char* const pstr) const;

    bool startsWith(const String& pstr) const;
    bool startsWith(const char* const pstr) const;
    bool startsWith(const String& pstr, int offset) const;
    bool startsWith(const char* const pstr, int offset) const;

    int compareTo(const String& pstr) const;
    int compareTo(const char* const pstr) const;
   
    int compareToIgnoreCase(const String& pstr) const;
    int compareToIgnoreCase(const char* pstr) const;

    bool equals(const String& str) const;
    bool equals(const char* const str) const;
   
    bool equalsIgnoreCase(const String& pstr) const;
    bool equalsIgnoreCase(const char* const pstr) const;

    int indexOf(char ch) const;
    int indexOf(char ch, int fromIndex) const;   
   
    //int indexOf(const char* const pstr) const;
    //int indexOf(const char* const pstr, int fromIndex) const;
    //int indexOf(const String& pstr) const;
    //int indexOf(const String& pstr, int fromIndex) const;

    int lastIndexOf(char ch) const;
    int lastIndexOf(char ch, int fromIndex) const;
   
    //int lastIndexOf(const char* const pstr) const;
    //int lastIndexOf(const char* const pstr, int fromIndex) const;
    //int lastIndexOf(const String& pstr) const;
    //int lastIndexOf(const String& pstr, int fromIndex) const;

    String* substring(int beginIndex) const;
    String* substring(int beginIndex, int endIndex) const;

    String& toUpperCase() const;
    String& toLowerCase() const;

    String& trim() const;
   
    char* toCharArray() const;
   
    char charAt(int index) const;
   
    String& replace(char oldChar, char newChar) const;
   
    String& operator=(const String& pstr);
    String& operator=(const char* const pstr);
};

#endif //definded RIZZIX_STRING_H


code:

/***************************************************************************
     String.cpp  - A C++ version of java.lang.String with added features
                             -------------------
    begin                : Sun Aug 31 2003
    copyright            : (C) 2003 by rizzix
    email                : rizzixs@fastmail.fm
 ***************************************************************************/

#include "String.h"

// Constructors and Destructors
String::String()
{
    len = 0;
    str = new char[1];   
}


String::String(const char* const pstr)
{
    len = 0;
    while (true) {
        if (pstr != 0 && *(pstr + len) != '\0') {
            len++;
        } else {
            break;
        }
    }
    len += 1;                                  // allocate space for '\0'
    if (len != 0) {
        str = new char[len];
        for (int i = 0; i < len; i++)
            str[i] = pstr[i];
        str[len - 1] = '\0';
    }
}


String::String(const String& pstr)
{
    str = pstr.toCharArray();
    len = pstr.length() + 1;
}


String::~String()
{
    len = 0;
    delete [] str; 
}


// returns the length of the string
inline int String::length() const
{
    return len - 1 ;
}


// returns a const char* const representation of the String
const char* const String::toString() const
{
    return (const char* const) str;
}


// returns a new String object with the argument appended
String& String::concat(const char* const pstr) const
{
    int argLength = 0;                          // length of the argument str
    while (true) {
        if (pstr != 0 && *(pstr + argLength) != '\0') {
            argLength++;
        } else {
            break;
        }
    }
   
    int newLength = length() + argLength;       // length of the new concat str
    newLength += 1;                             // allocate space for '\0'
   
    char tmpStr[newLength];
   
    if (newLength != 0) {                       // if there is something to add
        for (int i = 0; i < length(); i++)
            tmpStr[i] = str[i];
        for (int i = 0; i + length() < newLength; i++)
            tmpStr[i + length()] = pstr[i];
    }
    tmpStr[newLength - 1] = '\0';
   
    return *(new String(tmpStr));
}


// returns a new String object with the argument appended
String& String::concat(const String& pstr) const
{
    int newLength = length() + pstr.length() + 1;
    char tmpStr[newLength];
   
    if (newLength != 0) {                       // if there is something to add
        for (int i = 0; i < length(); i++)
            tmpStr[i] = str[i];
        for (int i = 0; i + length() < newLength; i++)
            tmpStr[i + length()] = pstr.charAt(i);
    }
    tmpStr[newLength - 1] = '\0';
   
    return *(new String(tmpStr));
}


// returns true if ends with argument
bool String::endsWith(const String& pstr) const
{
    if (pstr.length() > length()) return false;
   
    return startsWith(pstr, length() - (length() - pstr.length()));
}

bool String::endsWith(const char* const pstr) const
{
    bool matches = true;
    int tmplen = 0;
    while (true) {
        if (pstr != 0 && *(pstr + tmplen) != '\0') {
            tmplen++;
        } else {
            break;
        }
    }
   
    if (tmplen > length()) return false;
   
    for (int i = length() - 1; i >= length() - tmplen; i--)
        if (charAt(i) != pstr[tmplen - ((length() - 1) -  i) - 1]) {
            matches = false;
            break;
        }
       
    return matches;
}


// returns true if starts with argument String object
bool String::startsWith(const String& pstr) const
{
    return startsWith(pstr, 0);
}


// returns true if starts with argument const char*
bool String::startsWith(const char* const pstr) const
{
    return startsWith(pstr, 0);
}


// returns true if starts with argument String
// (from offset in this String object)
bool String::startsWith(const String& pstr, int offset) const
{
    if (offset > length() || pstr.length() > (length() - offset))
        return false;

    bool matches = true;
   
    for (int i = 0; i < pstr.length(); i++)
        if (charAt(i + offset) != pstr.charAt(i)) {
            matches = false;
            break;
        }
       
    return matches;
}


// returns true if starts with argument const char*
// (from offset in this String object)
bool String::startsWith(const char* const pstr, int offset) const
{
    bool matches = true;
    int tmplen = 0;
    while (true) {
        if (pstr != 0 && *(pstr + tmplen) != '\0') {
            tmplen++;
        } else {
            break;
        }
    }
   
    if (offset > length() || tmplen > (length() - offset))
        return false;
   
    for (int i = 0; i < tmplen; i++)
        if (charAt(i + offset) != pstr[i]) {
            matches = false;
            break;
        }
       
    return matches;
}


// returns 1 if greater, 0 if equals and -1 if less than
int String::compareTo(const String& pstr) const
{
    if (pstr.length() > length()) return 1;
    if (pstr.length() < length()) return -1;

    int psum = 0, sum = 0;
   
    for (int i = 0; i < pstr.length(); i++)
        psum += (int) pstr.charAt(i);
   
    for (int i = 0; i < length(); i++)
        sum += (int) charAt(i);
       
    if (psum > sum) {
        return 1;
    } else if (psum == sum) {
        return 0;
    } else {
        return -1;
    }
}


int String::compareTo(const char* const pstr) const
{
    int psum = 0, sum = 0;
   
    for (int i = 0; pstr[i] != '\0'; i++)
        psum += (int) pstr[i];
   
    for (int i = 0; i < length(); i++)
        sum += (int) charAt(i);
       
    if (psum > sum) {
        return 1;
    } else if (psum == sum) {
        return 0;
    } else {
        return -1;
    }
}


// same as compareTo, but ignoring the case
int String::compareToIgnoreCase(const String& pstr) const
{
    if (pstr.length() > length()) return 1;
    if (pstr.length() < length()) return -1;

    int psum = 0, sum = 0;
   
    for (int i = 0; i < pstr.length(); i++) {
        if (pstr.charAt(i) >= 97 && pstr.charAt(i) <= 122) {
            psum += (int) (pstr.charAt(i) - 32);
        } else {
            psum += (int) pstr.charAt(i);
        }
    }
   
    for (int i = 0; i < length(); i++) {
        if (charAt(i) >= 97 && charAt(i) <= 122) {
            sum += (int) (charAt(i) - 32);
        } else {
            sum += (int) charAt(i);
        }
    }
       
    if (psum > sum) {
        return 1;
    } else if (psum == sum) {
        return 0;
    } else {
        return -1;
    }
}


int String::compareToIgnoreCase(const char* const pstr) const
{
    int psum = 0, sum = 0;
   
    for (int i = 0; pstr[i] != '\0'; i++) {
        if (pstr[i] >= 97 && pstr[i] <= 122) {
            psum += (int) (pstr[i] - 32);
        } else {
            psum += (int) pstr[i];
        }
    }
   
    for (int i = 0; i < length(); i++) {
        if (charAt(i) >= 97 && charAt(i) <= 122) {
            sum += (int) (charAt(i) - 32);
        } else {
            sum += (int) charAt(i);
        }
    }
       
    if (psum > sum) {
        return 1;
    } else if (psum == sum) {
        return 0;
    } else {
        return -1;
    }
}


// returns true if this object's contents equals that of the argument
bool String::equals(const String& pstr) const
{
    return (compareTo(pstr) == 0);
}


bool String::equals(const char* const pstr) const
{
    return (compareTo(pstr) == 0);
}


// same as equals but ignoring the case
bool String::equalsIgnoreCase(const String& pstr) const
{
    return (compareToIgnoreCase(pstr) == 0);
}


bool String::equalsIgnoreCase(const char* const pstr) const
{
    return (compareToIgnoreCase(pstr) == 0);
}


// returns the index of char in the String, -1 if error
int String::indexOf(char ch) const
{
    return indexOf(ch, 0);
}


// returns the index of char in the sting from fromIndex onwards, -1 if error
int String::indexOf(char ch, int fromIndex) const
{
    if (fromIndex > length() || fromIndex < 0)
        return -1;
   
    int result = -1;
   
    for (int i = fromIndex; i < length(); i++)
        if (charAt(i) == ch) {
            result = i;
            break;
        }
       
    return result;
}

/*TODO: implement this
// returns the index of the substring pstr in the string, -1 if error
int String::indexOf(const String& pstr) const
{
   
}


int String::indexOf(const char* const pstr) const
{
   
}


// same as indexOf for substrings but from fromIndex onwards
int String::indexOf(const char* const pstr, int fromIndex) const
{
   
}


int String::indexOf(const String& pstr, int fromIndex) const
{
   
}
*/

// returns the index of char in the string,
// the string is read backwards. (this index is given as though you
// were reading the string forward, not backwards)
int String::lastIndexOf(char ch) const
{
    return lastIndexOf(ch, length() - 1);
}


int String::lastIndexOf(char ch, int fromIndex) const
{
    if (fromIndex > length() || fromIndex < 0)
        return -1;
   
    int result = -1;
   
    for (int i = fromIndex; i >= 0; i--)
        if (charAt(i) == ch) {
            result = i;
            break;
        }
       
    return result;
}

/*TODO: implement this
int String::lastIndexOf(const char* const pstr) const
{
   
}


int String::lastIndexOf(const char* const pstr, int fromIndex) const
{
   
}


int String::lastIndexOf(const String& pstr) const
{
   
}


int String::lastIndexOf(const String& pstr, int fromIndex) const
{
   
}
*/


// returns a new String that is a substring from beginIndex onwards,
// null if error
String* String::substring(int beginIndex) const
{
    return substring(beginIndex, length() - 1);
}


// returns a new String that is a substring from beginIndex to endIndex,
// null if error
String* String::substring(int beginIndex, int endIndex) const
{
    if (beginIndex > endIndex || beginIndex < 0 || beginIndex > length())
        return (String*) 0;
    if (endIndex < beginIndex || endIndex < 0 || endIndex > length())
        return (String*) 0;

    int pLength = endIndex - beginIndex + 2;  // allocate space for '\0' aswell
    char tmpStr[pLength];     
   
    for (int i = beginIndex; i <= endIndex; i++)
        tmpStr[i - beginIndex] = charAt(i);
       
    tmpStr[pLength - 1] = '\0';
   
    return new String(tmpStr);
}


// returns a new String that is the UPPER case version of this string
String& String::toUpperCase() const
{
    char tmpStr[length() + 1];
    for (int i = 0; i < length(); i++) {
        if (charAt(i) >= 97 && charAt(i) <= 122)
            tmpStr[i] = (char) (charAt(i) - 32);
        else
            tmpStr[i] = charAt(i);
    }
    tmpStr[length()] = '\0';
   
    return *(new String(tmpStr));
}


// returns a new String that is the lower case version of this string
String& String::toLowerCase() const
{
    char tmpStr[length() + 1];
    for (int i = 0; i < length(); i++) {
        if (charAt(i) >= 65 && charAt(i) <= 90)
            tmpStr[i] = (char) (charAt(i) + 32);
        else
            tmpStr[i] = charAt(i);
    }
    tmpStr[length()] = '\0';
   
    return *(new String(tmpStr));
}


// returns a new String object that is a trimmed version of this string
String& String::trim() const
{
    int begin = -1;
    int end = length() + 1;
   
    for (int i = 0; i < length(); i++)
        if (charAt(i) != ' ') {         // dot = space
            begin = i;                  // "....test...."
            break;                      //      ^-- thats where begin points to
        }
       
    for (int i = length() - 1; i >= 0; i--)
        if (charAt(i) != ' ') {         // dot = space
            end = i + 1;                // "....test...."
            break;                      //          ^-- where end points to
        }
     
    int newLength = (end - begin) + 1;
   
    if (end > begin) {
        char tmpStr[newLength];
   
        for (int i = 0; i < newLength; i++)
            tmpStr[i] = charAt(begin + i);
           
        tmpStr[newLength - 1] = '\0';
       
        return *(new String(tmpStr));
    } else {                            // if end <= begin then there is no str
        return *(new String(*this));    // or there are only spaces, so return
    }                                   // a copy of what we have.
}


//returns a new char* that has the same contents as that of this string object
char* String::toCharArray() const
{
    char* tmpStr = new char[length() + 1];
    for (int i = 0; i < length(); i++)
        tmpStr[i] = str[i];
    tmpStr[length()] = '\0';
    return tmpStr;       
}


// returns the char at int index, returns -1 if out of bounds
char String::charAt(int index) const
{
    if (index >= length() || index < 0)
        return -1;
    else
        return str[index];
}


// returns a new string that has the same contents of this String object
// with oldChar replaced with newChar
String& String::replace(char oldChar, char newChar) const
{
    char tmpStr[length() + 1];
   
    for (int i = 0; i < length(); i++) {
        if (charAt(i) == oldChar)
            tmpStr[i] = newChar;
        else
            tmpStr[i] = charAt(i);
    }
    tmpStr[length()] = '\0';
   
    return *(new String(tmpStr));
}


// overloaded operators
String& String::operator=(const String& pstr)
{
    delete [] str;
    str = pstr.toCharArray();
    len = pstr.length() + 1;
   
    return *this;
}


String& String::operator=(const char* const pstr)
{
    delete [] str;
    len = 0;
    while (true) {
        if (pstr != 0 && *(pstr + len) != '\0') {
            len++;
        } else {
            break;
        }
    }
   
    len += 1;                                   // allocate space for '\0'
   
    if (len != 0) {
        str = new char[len];
        for (int i = 0; i < len; i++)
            str[i] = pstr[i];
        str[len - 1] = '\0';
    }
    return *this;
}
Sponsor
Sponsor
Sponsor
sponsor
Display posts from previous:   
   Index -> Programming, C++ -> C++ Tutorials
View previous topic Tell A FriendPrintable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 1 Posts ]
Jump to:   


Style:  
Search: