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

  1. Arrays do not know their length
  2. Arrays cannot be assigned (use strcpy)
  3. Arrays can not be passed by value (use "const" reference)
  4. Arrays cannot be a return value of a function (use reference parameters)
  5. Arrays do not have "built-in" I/O (use loop and element I/O)
  6. Strings cannot be compared (use strcmp)

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):

rainbow.gif (2251 bytes)

 

void main(){
   int a[5];
   a[-6] = 45; // trash some memory outside the array
}

rainbow.gif (2251 bytes)

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:

  1. Construct by copying from C-style strings or another FixedString object
  2. Overload I/O operators
  3. Overload comparison operators
  4. Prevent storing characters outside space allowed
  5. Assignment, call by value and function return value will be free

 


We will use incremental build

 

 


 

 

FixedString Class: Specification (version 1)

(click for copy)

// 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 sizehptrd_left.gif (955 bytes)

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 hptrd_left.gif (955 bytes)
  // 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. hptrd_left.gif (955 bytes)
  // 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 hptrd_left.gif (955 bytes)
  FixedString( const FixedString & s ); hptrd_left.gif (955 bytes)
  // 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 hptrd_left.gif (955 bytes)
};
#endif



 

 


 

FixedString Class: Implementation (version 1)

(click for copy)

// 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 hptrd_left.gif (955 bytes)
//############ 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'); hptrd_left.gif (955 bytes)
	inp.ignore(1000,'\n'); // skip to end of line hptrd_left.gif (955 bytes)
	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'; hptrd_left.gif (955 bytes)
}

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); hptrd_left.gif (955 bytes)
	str[MaxSize] = '\0'; // in case "s" is too big hptrd_left.gif (955 bytes)
}

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? hptrd_left.gif (955 bytes)
}





 

FixedString Class: Testing (version 1)

(click for copy)

#include "fixedString.h"
void main()
{
	FixedString string0;

	cout << "string0 initially:" << string0 << endl;
	FixedString string1("hi there"); hptrd_left.gif (955 bytes)

	cout << "string1 initially: " << string1 << endl;
	cin >> string1; hptrd_left.gif (955 bytes)
	cout << "string1 after input: " << string1 << endl;
	

	FixedString string2(string1); hptrd_left.gif (955 bytes)

	cout << "string2 initially: " << string2 << endl;
	

}

 

FixedString Class: Specification (version 2)

(click for copy)

// 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)

(click for copy)

// 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)

(click for copy)


// Full version also tests assignment - click above
#include "fixedString.h"
void main()
{

	FixedString string1("Computer Science");
	FixedString string2("Electrical Engineering");

	if(string1 < string2) { hptrd_left.gif (955 bytes)
		cout << string1 << " is before " << string2 << endl;
	}
	else {
		cout << string1 << " is not before " << string2 << endl;
	}
	
	if(string1 < string1) { hptrd_left.gif (955 bytes)
		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.

(click for source code)

rainbow.gif (2251 bytes)
//###########################################################
// 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 hptrd_left.gif (955 bytes)
#define NAME_H
#include <iostream.h>
#include "FixedString.h" hptrd_left.gif (955 bytes)
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); hptrd_left.gif (955 bytes)
	// 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); hptrd_left.gif (955 bytes)
	// POST: constructs new Name object with copies of last and first
	void SetFirst(const char * first); hptrd_left.gif (955 bytes)
	// PRE: first is a string less than MaxSize
	// POST: sets first name to copy of first
	void SetFirst(const FixedString & first); hptrd_left.gif (955 bytes)
	// 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; hptrd_left.gif (955 bytes)
	//POST: returns copy of first name
	FixedString GetLast() const;
	//POST: returns copy of last name
private:
	FixedString firstName; hptrd_left.gif (955 bytes)
	FixedString lastName;
};
#endif

rainbow.gif (2251 bytes)

 

//###########################################################
// 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 hptrd_left.gif (955 bytes) << endl;
	oStream << "Last Name:" << thisName.lastName << endl;
	return oStream;
}
istream & operator >>(istream & iStream, Name & thisName)
{
	cout << "First Name:"; hptrd_left.gif (955 bytes)
	iStream >> thisName.firstName; hptrd_left.gif (955 bytes)
	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) hptrd_left.gif (955 bytes)
	// 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)	hptrd_left.gif (955 bytes)
	// 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 hptrd_left.gif (955 bytes)
	firstName = tempString; hptrd_left.gif (955 bytes)
}
void Name::SetFirst(const FixedString &hptrd_left.gif (955 bytes) 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; hptrd_left.gif (955 bytes)
}
FixedString Name::GetLast() const
	//POST: returns copy of last name
{
	return lastName;
}

rainbow.gif (2251 bytes)

 

#include "Name.h"
void main()
{
	Name name1;
	cout << "name1 initially:\n" << name1 << endl; hptrd_left.gif (955 bytes)
	cin >> name1; hptrd_left.gif (955 bytes)
	cout << "name1 after input:\n" << name1 << endl; 
	Name name2("Chris", "Wild"); hptrd_left.gif (955 bytes)
	cout << "name2 initially:\n" << name2 << endl;
	name2.SetFirst("John"); hptrd_left.gif (955 bytes)
	cout << "name2 after set First:\n" << name2 << endl;
	name1 = name2; hptrd_left.gif (955 bytes)
	cout << "name1 First after assignment:" << name1.GetFirst() hptrd_left.gif (955 bytes) << endl;
	cout << "name1 Last after assignment:" << name1.GetLast() << endl;
}

rainbow.gif (2251 bytes)


Copyright chris wild 1998.
For problems or questions regarding this website contact [Chris Wild (e-mail:wild@cs.odu.edu].
Last updated: September 21, 1998.