CS 250 Computer Programming and Problem Solving - FALL 1998 |
---|
[ Home | Syllabus | Notes | Glossary | CS250 WEB Version Home Page ]
FixedString: Example
FixedString Class: Motivation
C-Style Strings inherit a number of problems from "arrays" since a string is a character array
The first leads to very dangerous situations which are not detected by the compiler and sometimes even excape dectection at run time. Consider the following program (click here for copy):
void main(){ int a[5]; a[-6] = 45; // trash some memory outside the array }
What would your compiler do?
What might happen?
To solve these problems, let's define a new object called FixedString (fixed because it will have space for 256 characters whether you need it or not - we will change this later) with the following features:
We will use incremental build
FixedString Class: Specification (version 1)
// FIXEDSTRING.H - FixedString class definition // Fixed-length string class: allocate 256 characters for every string // Makes strings first class objects: Version 1 // Construct from C-style strings // or by Copying another FixedString Object // Overload I/O operators #ifndef FIXEDSTRING_H // see page 96 for explanation #define FIXEDSTRING_H #include <iostream.h> #include <iomanip.h> const int MaxSize = 256; // Maximum allowable string size class FixedString { friend istream & operator >>( istream & inp, FixedString & s ); // Reads a string from the input stream defined as // POST: if the rest of the current line is less than MaxSize characters // then reads rest of line and skips over the newline // If exactly MaxSize characters, then reads MaxSize and skips newline // Otherwise reads MaxSize and skips rest of characters and the newline friend ostream & operator <<( ostream & inp, const FixedString & s ); // Writes string to output stream // POST: write using standard insertion operator public: FixedString(); FixedString( const char * s ); // Construct from a C-style string. // PRE: s is a string less than MaxSize characters // POST: constructs new string copying string "s" // if "s" is more than 256 characters, only uses first 256 FixedString( const FixedString & s ); // Construct from another FixedString. // PRE: "s" is valid FixedString (less or equal MaxSize characters) // POST: constructs new string with a copy of "s" private: char str[MaxSize+1]; // String characters }; #endif
FixedString Class: Implementation (version 1)
// FIXEDSTRING.CPP - FixedString member function definitions // Fixed-length string class: allocate 256 characters for every string // Makes strings first class objects: Version 1 // Construct from C-style strings // or by Copying another FixedString Object // Overload I/O operators #include "fixedString.h" #include <string.h> // build on C-style strings
//############ Define friends
istream & operator >>( istream & inp, FixedString & s ) // Reads a string from the input stream defined as // POST: if the rest of the current line is less than MaxSize characters // then reads rest of line and skips over the newline // If exactly MaxSize characters, then reads MaxSize and skips newline // Otherwise reads MaxSize and skips rest of characters and the newline { inp.get(s.str,MaxSize+1,'\n'); inp.ignore(1000,'\n'); // skip to end of line return inp; } ostream & operator <<( ostream & outp, const FixedString & s ) // Writes string to output stream // POST: write using standard insertion operator { outp << s.str; return outp; } //############ Define member functions FixedString::FixedString() { str[0] = '\0'; } FixedString::FixedString( const char * s ) // Construct from a C-style string. // PRE: s is a string less than MaxSize characters // POST: constructs new string copying string "s" // if "s" is more than 256 characters, only uses first 256 { strncpy(str,s,MaxSize); str[MaxSize] = '\0'; // in case "s" is too big } FixedString::FixedString( const FixedString & s ) // Construct from another FixedString. // PRE: "s" is valid FixedString (less or equal MaxSize characters) // POST: constructs new string with a copy of "s" { strncpy(str, s.str, MaxSize); str[MaxSize] = '\0'; // in case "s" is too big //- should never happen but who knows? }
FixedString Class: Testing (version 1)
#include "fixedString.h" void main() { FixedString string0; cout << "string0 initially:" << string0 << endl; FixedString string1("hi there"); cout << "string1 initially: " << string1 << endl; cin >> string1; cout << "string1 after input: " << string1 << endl; FixedString string2(string1); cout << "string2 initially: " << string2 << endl; }
FixedString Class: Specification (version 2)
// FIXEDSTRING.H - FixedString class definition // Fixed-length string class: allocate 256 characters for every string // Makes strings first class objects: Version 2 // Construct from C-style strings // or by Copying another FixedString Object // Overload I/O operators // Overload comparison operators (only "<" shown here - click above for full class) #ifndef FIXEDSTRING_H // see page 96 for explanation #define FIXEDSTRING_H #include <iostream.h> #include <iomanip.h> const int MaxSize = 256; // Maximum allowable string size class FixedString { friend istream & operator >>( istream & inp, FixedString & s ); // Reads a string from the input stream defined as // POST: if the rest of the current line is less than MaxSize characters // then reads rest of line and skips over the newline // If exactly MaxSize characters, then reads MaxSize and skips newline // Otherwise reads MaxSize and skips rest of characters and the newline friend ostream & operator <<( ostream & inp, const FixedString & s ); // Writes string to output stream // POST: write using standard insertion operator
friend bool operator <(const FixedString & s1, const FixedString & s2); // compares s1 and s2 // POST: returns true if s1 is alphabetically before s2 // else returns false
public: FixedString(); FixedString( const char * s ); // Construct from a C-style string. // PRE: s is a string less than MaxSize characters // POST: constructs new string copying string "s" // if "s" is more than 256 characters, only uses first 256 FixedString( const FixedString & s ); // Construct from another FixedString. // PRE: "s" is valid FixedString (less or equal MaxSize characters) // POST: constructs new string with a copy of "s"
private: char str[MaxSize+1]; // String characters }; #endif
FixedString Class: Implementation (version 2)
// FIXEDSTRING.CPP - FixedString member function definitions // Fixed-length string class: allocate 256 characters for every string // Makes strings first class objects: Version 2 // Construct from C-style strings // or by Copying another FixedString Object // Overload I/O operators // Overload comparison operators (only "<" shown here - click above for full implementation) #include "fixedString.h" #include <string.h> // build on C-style strings //############ Define friends
bool operator <(const FixedString & s1, const FixedString & s2) // compares s1 and s2 // POST: returns true if s1 is alphabetically before s2 // else returns false { if(strcmp(s1.str,s2.str) < 0) return true; else return false; }
istream & operator >>( istream & inp, FixedString & s ) // Reads a string from the input stream defined as // POST: if the rest of the current line is less than MaxSize characters // then reads rest of line and skips over the newline // If exactly MaxSize characters, then reads MaxSize and skips newline // Otherwise reads MaxSize and skips rest of characters and the newline { inp.get(s.str,MaxSize+1,'\n'); inp.ignore(1000,'\n'); // skip to end of line (hopefully) return inp; } ostream & operator <<( ostream & outp, const FixedString & s ) // Writes string to output stream // POST: write using standard insertion operator { outp << s.str; return outp; }
//#### Define member functions FixedString::FixedString() { str[0] = '\0'; } FixedString::FixedString( const char * s ) // Construct from a C-style string. // PRE: s is a string less than MaxSize characters // POST: constructs new string copying string "s" // if "s" is more than 256 characters, only uses first 256 { strncpy(str,s,MaxSize); str[MaxSize] = '\0'; // in case "s" is too big } FixedString::FixedString( const FixedString & s ) // Construct from another FixedString. // PRE: "s" is valid FixedString (less or equal MaxSize characters) // POST: constructs new string with a copy of "s" { strncpy(str, s.str, MaxSize); str[MaxSize] = '\0'; // in case "s" is too big //- should never happen but who knows? }
FixedString Class: Testing (version 2)
// Full version also tests assignment - click above
#include "fixedString.h" void main() { FixedString string1("Computer Science"); FixedString string2("Electrical Engineering"); if(string1 < string2) { cout << string1 << " is before " << string2 << endl; } else { cout << string1 << " is not before " << string2 << endl; } if(string1 < string1) { cout << string1 << " is before " << string1 << endl; } else { cout << string1 << " is not before " << string1 << endl; } }
Using FixedString in another class
Let's define a new class called "Name" which
stores a person's first and last names
and which uses FixedString for that purpose.
//########################################################### // NAME: class containing a person's name (version 1) // Name contains a first and last name // Implements input/output overloads and access and modifier functions // has both default and tow non-default constructors allowing // construction from both C-style and FixedString objects // Programmer: Chris Wild //###########################################################
#ifndef NAME_H #define NAME_H #include <iostream.h> #include "FixedString.h"
class Name { friend ostream & operator <<(ostream & oStream, const Name & thisName); friend istream & operator >>(istream & iStream, Name & thisName);
public: Name(); //POST: first and last names are empty
Name(const char * first, const char * last); // PRE: last and first are strings less than MaxSize // POST: constructs new Name object with copies of last and first
Name(const FixedString & first, const FixedString & last); // POST: constructs new Name object with copies of last and first
void SetFirst(const char * first); // PRE: first is a string less than MaxSize // POST: sets first name to copy of first
void SetFirst(const FixedString & first); // POST: sets first name to copy of first
void SetLast(const char * last); // PRE: last is a string less than MaxSize // POST: sets last name to copy of last
void SetLast(const FixedString & last); // POST: sets last name to copy of lastName
FixedString GetFirst() const; //POST: returns copy of first name
FixedString GetLast() const; //POST: returns copy of last name
private: FixedString firstName; FixedString lastName; }; #endif
//########################################################### // NAME: class containing a person's name (version 1) // Name contains a first and last name // Implements input/output overloads and access and modifier functions // has both default and tow non-default constructors allowing // construction from both C-style and FixedString objects // Programmer: Chris Wild //###########################################################
#include "Name.h"
ostream & operator <<(ostream & oStream, const Name & thisName) { oStream << "First Name:" << thisName.firstName << endl; oStream << "Last Name:" << thisName.lastName << endl; return oStream; } istream & operator >>(istream & iStream, Name & thisName) { cout << "First Name:"; iStream >> thisName.firstName; cout << "Last Name:"; iStream >> thisName.lastName;
return iStream; }
Name::Name() //POST: first and last names are empty { // this happens automatically using default constructors of FixedString }
Name::Name(const char * first, const char * last): firstName(first), lastName(last) // PRE: lastName and firstName are strings less than MaxSize // POST: constructs new Name object with copies of lastName and first { // all work done in constructor initializer }
Name::Name(const FixedString & first, const FixedString & last) : firstName(first), lastName(last) // POST: constructs new Name object with copies of last and first { // all work done in constructor initializer }
void Name::SetFirst(const char * first) // PRE: first is a string less than MaxSize // POST: sets first name to copy of first // because we have not yet overloaded the assignment operator // for C-Style strings. // will take a round about route to accomplish this // create temporary FixedString object and then assignemt { FixedString tempString(first); // initial to C-style string
firstName = tempString; }
void Name::SetFirst(const FixedString & first) // POST: sets first name to copy of first { firstName = first; }
void Name::SetLast(const char * last) // PRE: last is a string less than MaxSize // POST: sets last name to copy of last // because we have not yet overloaded the assignment operator // for C-Style strings. // will take a round about route to accomplish this // create temporary FixedString object and then assignemt { FixedString tempString(last); // initial to C-style string
lastName = tempString; } void Name::SetLast(const FixedString & last) // POST: sets last name to copy of last { lastName = last; }
FixedString Name::GetFirst() const //POST: returns copy of first name { return firstName; }
FixedString Name::GetLast() const //POST: returns copy of last name { return lastName; }
#include "Name.h"
void main() { Name name1; cout << "name1 initially:\n" << name1 << endl;
cin >> name1; cout << "name1 after input:\n" << name1 << endl;
Name name2("Chris", "Wild"); cout << "name2 initially:\n" << name2 << endl;
name2.SetFirst("John"); cout << "name2 after set First:\n" << name2 << endl;
name1 = name2;
cout << "name1 First after assignment:" << name1.GetFirst() << endl; cout << "name1 Last after assignment:" << name1.GetLast() << endl;
}