Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

viper35al

String class problems

This topic is 5596 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This code has given me alot of problems. I''ve spent hours going through this code slowly, but I still have some questions my questions are commented in my trouble areas. Thanks in advance.
  
//Listing 12.12


#include <iostream.h>
#include <string.h>

class String
{
public:
	// constructors

	String();
	String(const char *const);
	String(const String &);
	~String();

	char & operator[](unsigned short offset);
	char operator[](unsigned short offset) const;
	String operator+(const String&);
	void operator+=(const String&);
	String & operator= (const String &);

	// General accessors

	unsigned short GetLen()const { return itsLen; }
	const char * GetString() const { return itsString; }

private:
	String (unsigned short);         
	char * itsString;
	unsigned short itsLen;
};

String::String()
{
	itsString = new char[1];
	itsString[0] = ''\0'';
	itsLen=0;
// why not have [0] instead of [1]?  Isn''t itsString only 

//taking one char?


}


String::String(unsigned short len)
{
	itsString = new char[len+1];
	for (unsigned short i = 0; i<=len; i++)
		itsString[i] = ''\0'';
	itsLen=len;
}

String::String(const char * const cString)
// why char * cString?  Isn''t it being sent in a sentence?

//why not take the value of the sentence.  How does this covert

// a sentence to a pointer?



{
	itsLen = strlen(cString);
	itsString = new char[itsLen+1];
	for (unsigned short i = 0; i<itsLen; i++)
		itsString[i] = cString[i];
	itsString[itsLen]=''\0'';
}


String::String (const String & rhs)
{
	itsLen=rhs.GetLen();
	itsString = new char[itsLen+1];
	for (unsigned short i = 0; i<itsLen;i++)
		itsString[i] = rhs[i];
	itsString[itsLen] = ''\0'';
}

String::~String ()
{
	delete [] itsString;
	itsLen = 0;
}

String& String::operator=(const String & rhs)
{
	if (this == &rhs)
// why &rhs and not just rhs?  What does the & stand for in this

// situation?  An adress?  A reference?  

		return *this;
	delete [] itsString;
	itsLen=rhs.GetLen();
	itsString = new char[itsLen+1];
	for (unsigned short i = 0; i<itsLen;i++)
		itsString[i] = rhs[i];
	itsString[itsLen] = ''\0'';
	return *this;
}

char & String::operator[](unsigned short offset)
{
	if (offset > itsLen)
		return itsString[itsLen-1];
	else
		return itsString[offset];
}

char String::operator[](unsigned short offset) const
{
	if (offset > itsLen)
		return itsString[itsLen-1];
	else
		return itsString[offset];
}

String String::operator+(const String& rhs)
{
	unsigned short  totalLen = itsLen + rhs.GetLen();
	String temp(totalLen);
	unsigned short i;
	for ( i= 0; i<itsLen; i++)
		temp[i] = itsString[i];
	for (unsigned short j = 0; j<rhs.GetLen(); j++, i++)
		temp[i] = rhs[j];
	temp[totalLen]=''\0'';
	return temp;
}

void String::operator+=(const String& rhs)
{
	unsigned short rhsLen = rhs.GetLen();
	unsigned short totalLen = itsLen + rhsLen;
	String  temp(totalLen);
	unsigned short i;
	for (i = 0; i<itsLen; i++)
		temp[i] = itsString[i];
	for (unsigned short j = 0; j<rhs.GetLen(); j++, i++)
		temp[i] = rhs[i-itsLen];
	temp[totalLen]=''\0'';
	*this = temp;
}

int main()
{
	String s1("initial test");
	cout << "S1:\t" << s1.GetString() << endl;

	char * temp = "Hello World";
	s1 = temp;
// when s1 = temp the compiler goes to this constructor

//String::String(const char * const cString)

//how does the compiler know to go to this before the 

// operator = method?


cout << "S1:\t" << s1.GetString() << endl;

	char tempTwo[20];
	strcpy(tempTwo,"; nice to be here!");
	s1 += tempTwo;
	cout << "tempTwo:\t" << tempTwo << endl;
	cout << "S1:\t" << s1.GetString() << endl;

	cout << "S1[4]:\t" << s1[4] << endl;
	s1[4]=''x'';
	cout << "S1:\t" << s1.GetString() << endl;

	cout << "S1[999]:\t" << s1[999] << endl;

	String s2(" Another string");
	String s3;
	s3 = s1+s2;
	cout << "S3:\t" << s3.GetString() << endl;

	String s4;
	s4 = "Why does this work?";
	cout << "S4:\t" << s4.GetString() << endl;
	return 0;
}


  

Share this post


Link to post
Share on other sites
Advertisement
quote:

String::String()
{
itsString = new char[1];
itsString[0] = ''\0'';
itsLen=0;
// why not have [0] instead of [1]? Isn''t itsString only
//taking one char?
}


Doing new char[0] will allocate 0 bytes, not 1. You are allowed to allocate 0 bytes, but then you have no memory to do anything with.

quote:

String::String(const char * const cString)
// why char * cString? Isn''t it being sent in a sentence?
//why not take the value of the sentence. How does this covert
// a sentence to a pointer?
{
itsLen = strlen(cString);
itsString = new char[itsLen+1];
for (unsigned short i = 0; i itsString = cString[i];
itsString[itsLen]=''\0'';
}


In C and C++ pointers can be treated like arrays. The difference is what they point at. An array of characters is considered a native C string.

quote:

String& String::operator=(const String & rhs)
{
if (this == &rhs)
// why &rhs and not just rhs? What does the & stand for in this
// situation? An adress? A reference?


& is also the dereferencing operator. It takes the address of rhs, which in this case is convoluted because rhs is a reference.
So &rhs is the address of the parameter passed to operator=.
They are checking to make certain they are not assigning the string to itself, because they mindlessly destroy the string buffer of ''this'' prior to reallocating a new buffer and copying rhs.
This code is not exception safe, and was not written by a C++ expert. One could claim that the exception safety is implicit for this case, and that the nothrow() required of the members of the class. However the code as written does not have a nothrow guarantee (new can throw), nor is it efficient. (It''s good enough for casual use though.)

quote:

int main()
{
String s1("initial test");
cout << "S1:\t" << s1.GetString() << endl;

char * temp = "Hello World";
s1 = temp;
// when s1 = temp the compiler goes to this constructor
//String::String(const char * const cString)
//how does the compiler know to go to this before the
// operator = method?



It ought to call String::String(const char * const cString) on this line:
String s1("initial test");

and String::operator=(const String& rhs) on:
s1 = temp;



There''s a string stream object that can be used as a replacement for the old C string library. Also, C++ already has a string class.

  
#include <iostream>
#include <sstream>

#include <windows.h>

int main()
{
using namespace std;
std::stringstream ss;
ss << "This is a string stream" << endl;
ss << "It works kinda like cout" << endl;
cout << ss.str(); //.str() returns a std::string


ss.str(""); //resets the string stream buffer to ""

ss << "
You can even use it with legacy C functions";
ss << "
that expect char*''s" << endl;

OutputDebugString(ss.str().c_str());

}

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!