1 / 43

C String, Proper Type, and String Objects

C String, Proper Type, and String Objects . Andy Wang COP 4530: Data Structures, Algorithms, and Generic Programming. Lecture Overview. Goal Design a string class that overcomes the disadvantages of C strings Roadmap Critique of C strings The need for proper type

dyani
Télécharger la présentation

C String, Proper Type, and String Objects

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. C String, Proper Type, and String Objects Andy Wang COP 4530: Data Structures, Algorithms, and Generic Programming

  2. Lecture Overview • Goal • Design a string class that overcomes the disadvantages of C strings • Roadmap • Critique of C strings • The need for proper type • String objects

  3. In-Class Exercise Write a C function that copies one string to another. void strcpy(char *dest, char *src) { … }

  4. Assumptions of C Strings • Allocated memory char *str; str = malloc(sizeof(char)*11); • Null termination str[10] = “\0” strcpy(str, “0123456789”);

  5. What if the string is not null terminated? What if the string is not allocated? What can go wrong? void strcpy(char *copy_cat, char *cat) { int j; for (j = 0; cat[j] != ‘\0’; j++) { copy_cat[j] = cat[j]; } copy_cat[j] = ‘\0’; }

  6. Other String Functions • Still assume null-terminated strings • Still assume allocated memory • Security holes… • Internet worms • System break-ins

  7. The Concept of Proper Type • A proper type should be • Responsible for its own data • Data protected from clients and other programs • Responsible for its own behavior • Make behavior available to clients • Implementation hidden from the public view • Responsible for its own existence • Automatic memory management

  8. C++ Class Objects • Responsible for their own data • Protected or private data • Controlled access through public methods • Responsible for their own behavior • Public methods • Responsible for their own existence • Constructors/deconstructors

  9. In-Class Exercise: String Class namespace rcl { class String { // friend… public: // … private: // … } // … }

  10. String Class class String { // friend iostream operators public: // constructors/destructors // operators // builders // data accessors (const) // string comparison function private: // data // helper methods } // equality and order comparison operators

  11. Private Data char *str; unsigned int size; // equal to C strlen(); class String { // friend iostream operators public: // constructors/destructors // operators // builders // data accessors (const) // String comparison function private: // data // helper methods } // equality and order comparison operators

  12. Data Accessors unsigned int Size() const; unsigned int Length() const; char Element(unsigned int n) const; class String { // friend iostream operators public: // constructors/destructors // operators // builders // data accessors (const) // String comparison function private: // data // helper methods } // equality and order comparison operators

  13. Data Accessors unsigned int String::Size() const { return size; } unsigned int String::Length() const { // note: strlen takes char*; therefore, we need to implement an operator that converts String to char*. return strlen(*this); }

  14. In-Class Exercise: Element Return the nth character of the String. Watch out for boundary cases. char String::Element(unsigned int n) const { … }

  15. Element char String::Element(unsigned int n) const { char ch; if ((size == 0) || (n >= size)) { return ‘\0’; } else { return str[n]; } }

  16. String Comparison Function static int StrCmp(const String&, const String&) class String { // friend iostream operators public: // constructors/destructors // operators // builders // data accessors (const) // String comparison function private: // data // helper methods } // equality and order comparison operators

  17. StrCmp int String::StrCmp(const String& S1, const String& S2) { if ((S1.Size() == 0) && (S2.Size() == 0)) { return 0; } else if ((S1.Size() == 0) && (S2.Size() != 0)) { return –1; } else if ((S1.Size() != 0) && (S2.Size() == 0)) { return 1; } else { return (strcmp(S1.str, S2.str); } }

  18. Equality Operators int operator==(const String& S1, const String& S2); int operator!=(const String& S1, const String& S2); int operator<(const String& S1, const String& S2); int operator<=(const String& S1, const String& S2); int operator>=(const String& S1, const String& S2); int operator>(const String& S1, const String& S2); class String { // friend iostream operators public: // constructors/destructors // operators // builders // data accessors (const) // String comparison function private: // data // helper methods } // equality and order comparison operators

  19. Comparison Operators int operator==(const String& S1, const String& S2) { return (String::StrCmp(S1, S2) == 0); } int operator!=(const String& S1, const String& S2) { return (String::StrCmp(S1, S2) != 0); } int operator>(const String& S1, const String& S2) { return (String::StrCmp(S1, S2) > 0); }

  20. Comparison Operators int operator>=(const String& S1, const String& S2) { return (String::StrCmp(S1, S2) >= 0); } int operator<(const String& S1, const String& S2) { return (String::StrCmp(S1, S2) < 0); } int operator<=(const String& S1, const String& S2) { return (String::StrCmp(S1, S2) <= 0); }

  21. Helper Methods static void Error(const char*); static char* newstr(int n); static int xstrlen(const char*); static void xstrcpy(char *, const char*); void Clear(); void Clone(const String& S); class String { // friend iostream operators public: // constructors/destructors // operators // builders // data accessors (const) // String comparison function private: // data // helper methods } // equality and order comparison operators

  22. Error void String::Error(const char* msg) { cerr << “** String error: “ << msg << ‘\n’; exit(EXIT_FAILURE); }

  23. In-Class Exercise: newstr It creates a new String of size n (C String with an array size of n + 1). void String::newstr(int n) { … }

  24. newstr char *String::newstr(int n) { char *Cptr = 0; if (n >= 0) { Cptr = new char[n + 1]; if (Cptr == 0) { Error(“memory allocation failure”) } Cptr[n] = ‘\0’; } return Cptr; }

  25. xstrlen int String::xstrlen(const char* s) { int len; if (s != 0) { // check for null pointer for (len = 0; s[len] != ‘\0’; ++len) { } } return len; }

  26. xstrcpy void String::xstrcpy(char *dest, const char *src) if (src != 0) { // check for null pointer if (dest != 0) { // check for null pointer int j; for (j = 0; src[j] != ‘\0’; ++j) { dest[j] = src[j]; } dest[j] = ‘\0’; } else { Error(“xstrcpy: null destination”); } } }

  27. In-Class Exercise: Clear If the String has storage allocated, delete it, and set the storage pointer and size to zero. void Clear() { … }

  28. Clear void String::Clear() { if (str) { delete[] str; str = 0; size = 0; } }

  29. In-Class Exercise: Clone If makes a copy of the parameter S. void *String::Clone(const String& S) { … }

  30. Clone void String::Clone(const String& S) { size = S.Size(); if (size > 0) { str = newstr(size); xstrcpy(str, S.str); } else { str = 0; } }

  31. Operators String &operator=(const String& S); char &operator[] (unsigned int I) const; operator const char* () const class String { // friend iostream operators public: // constructors/destructors // operators // builders // data accessors (const) // String comparison function private: // data // helper methods } // equality and order comparison operators

  32. Operator= String &String::operator=(const String& S) { if (this != &S) { Clear(); Clone(S); } return *this; }

  33. Operator[] char& String::operator[] (unsigned int n) const { if ((size == 0) || (n > size)) { Error(“index out of range”); } return str[n]; }

  34. Operator const char* String::operator const char* () const { return str; }

  35. Builder Functions void Wrap(const char* Cptr); void GetLine(istream& inl); int SetSize(unsigned int sz, char fill); class String { // friend iostream operators public: // constructors/destructors // operators // builders // data accessors (const) // String comparison function private: // data // helper methods } // equality and order comparison operators

  36. Wrap void String::Wrap(const char* Cptr) { Clear(); if (Cptr) { size = xstrlen(Cptr); str = newstr(size); xstrcpy(str, Cptr); } }

  37. GetLine void String::GetLine(istream& is) { unsigned int curr_size = 0, buff_size = init_buff_size; char *buffer = new char[buff_size + 1]; for (char x = is.get(); ((x != ‘\n’) && (!is.eof()); x = is.get()) { if (curr_size == buff_size) { buff_size *= 2; char *newbuffer = new char[buff_size + 1]; // copy buffer to newbuffer delete[] buffer; buffer = newbuffer; } buffer[curr_size++] = x; } buffer[curr_size] = ‘\0’; Wrap(buffer); delete[] buffer; }

  38. SetSize int String::SetSize(unsigned int sz, char fill) { if (sz != Size()) { char *newdata = newstr(sz); if (newdata == 0) return 0; unsigned int j; if (sz < Size()) { for (j = 0; j < sz; ++j) { newdata[j] = str[j]; } } else { for (j = 0; j < Size(); ++j) { newdata[j] = str[j]; } for (j = Size(); j < sz; ++j) { newdata[j] = fill; } delete[] str; str = newdata; size = sz; } } return 1; }

  39. Constructors/Destructors String(); explicit String(const char* Cptr); ~String(); String (const String &S); class String { // friend iostream operators public: // constructors/destructors // operators // builders // data accessors (const) // String comparison function private: // data // helper methods } // equality and order comparison operators

  40. Constructors /Deconstructors String::String() : str(0), size(0) {} String::String(const char *Cptr) : str(0), size(0) { Wrap(Cptr); } String::String(const String& S) { Clone(S); } String::~String() { if (str) delete[] str; }

  41. I/O Operators friend ostream& operator<<(ostream& os, const String& S); friend istream& operator>>(istream& is, String S); class String { // friend iostream operators public: // constructors/destructors // operators // builders // data accessors (const) // String comparison function private: // data // helper methods } // equality and order comparison operators

  42. Operator<< ostream& operator<<(ostream& os, const String& S) { os << S.str; return os; }

  43. Operator>> istream& operator>>(istream &is, String &S) { unsigned int curr_size = 0; buff_size = init_buff_size; char x; // skip clear space char *buffer = String::newstr(buff_size); buffer[curr_size++] = x; for (x = is.peek(); (// x is not white space or eof); x = is.peek()) { if (curr_size == buff_size) { buff_size *= 2; char *newbuffer = String::newstr(buff_size); // copy buffer into newbuffer delete[] buffer; buffer = newbuffer; } buffer[curr_size++] = x; is.get(); } buffer[curr_size] = ‘\0’; S.Wrap(buffer); delete[] buffer; return is; }

More Related