By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,238 Members | 1,746 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,238 IT Pros & Developers. It's quick & easy.

Problems with a string function in C++

P: n/a
I have written two classes : a String Class based on the book " C++ in
21 days " and a GenericIpClass listed below :

file GenericStringClass.h

// Generic String class

class String
{
public:

// constructors

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

// overloaded operators

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 members

private:
String(unsigned short);

// protected members for use in other classes

protected:
char * itsString;
unsigned short itsLen;
};
// default constructor creates a string of zero bytes

String::String()
{
itsString = new char[1];
itsString[0] = '\0';
itsLen=0;
}
// Creates a String object with predefined size "len"
// Null filled .

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

// Converts an array of characters into a String object

String::String(const char * const charArray)
{
itsLen=strlen(charArray);
itsString= new char[itsLen+1];
for (unsigned short i=0; i<itsLen; i++)
{
itsString[i]=charArray[i];
}
itsString[itsLen]='\0';
}
// copy constructor

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';
}

// destructor frees allocated memory
String::~String()
{
delete [] itsString;
itsLen=0;
}

// operator equals

String& String::operator=(const String & rhs)
{
if (this == &rhs)
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 ;
}
// non constant offset operator
// returns reference to a character so it can be changed
char & String::operator[](unsigned short offset)
{
if(offset > itsLen)
{
return itsString[itsLen-1];
}
else
{
return itsString[offset];
}
}
// constant offset operator
char String::operator[](unsigned short offset) const
{
if(offset > itsLen)
{
return itsString[itsLen-1];
}
else
{
return itsString[offset];
}
}

// Creates new string by adding current to rhs
String String::operator+(const String& rhs)
{
unsigned short totalLen = itsLen + rhs.GetLen();
String temp(totalLen);
for( unsigned short i=0; i<itsLen; i++)
{
temp[i]=itsString[i];
}
for (unsigned short j=0; j<rhs.GetLen(); j++,i++)
{
temp[i]=rhs[j];
printf("This is rhs ....%c \n",(char) rhs[j]);
}
temp[totalLen]='\0';
return temp;
}
// changes current String by adding another istance of the object clas
void String::operator+=(const String &rhs)
{
unsigned short rhsLen = rhs.GetLen();
unsigned short totalLen = itsLen + rhsLen;
String temp(totalLen);
for(unsigned short i=0; i<totalLen ; 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;
}

file GenIpClass.cpp

#include <iostream.h>
#include <stdio.h>
#include <string.h>
#include "GenericStringClass.h"

// General definitions for the GenericIPClass

#ifndef __IP_STATUS_
enum __IP_STATUS_ {__ACTIVE,__INACTIVE};
#endif

#ifndef LOOPBACK
#define LOOPBACK "127.0.0.1"
#endif

#ifndef _HTTP_PREFIX
String _HTTP_PREFIX("http://");
#endif

#define DOT '.'
// GenericIpAddress Class mainly used for checking a given IP for
validity
// so you don't need to open a socket for nothing also used for
forming
// http address for requesting stats such
http://192.20.4.4/features.html
// with a given ip address of 192.20.4.4
class GenericIpAddress : public String
{
public:

// constructors ..

GenericIpAddress(); // for what reason is that used ??
GenericIpAddress(const char* const);
GenericIpAddress(String &);
~GenericIpAddress();

// Accessors

bool isIpValid();
String & GetIpAddress();

private:
String itsIpAddress;
unsigned short ipLength;

protected:
__IP_STATUS_ itsStatus;
};

// This is constructor exists only if
// you have an empty declaration by mistake
GenericIpAddress::GenericIpAddress()
{
// do nothing ...
}
GenericIpAddress::GenericIpAddress(const char * const GivenIp)
{
// Here we used the overloaded = constructor from the String
class
// GivenIp has to be a const char *

itsIpAddress=GivenIp;
}
GenericIpAddress::~GenericIpAddress()
{
// do nothing !!

}
String & GenericIpAddress::GetIpAddress(void)
{
return itsIpAddress;
}
bool GenericIpAddress::isIpValid(void)
{

String tempString=this->GetIpAddress();
cout << "DEBUG " << endl ;
cout << tempString.GetString() << endl;
cout << "DEBUG " << endl ;
unsigned short ip_length = tempString.GetLen();
unsigned short int m;
m=0;
int k[3];
int ip_part;
if((ip_length < 7 ) || (ip_length > 15))
{
cout << "Returning false ..... " << endl;
return false ;
}
for(unsigned short i=0; i<ip_length; i++)
{
if((tempString[i]>'0') && (tempString[i]<'9'))
{
cout << "inside first if statement " <<
tempString[i] << endl;
k[m]=(int)tempString[i];
m=m+1;
}
if((tempString[i]==DOT))
{
cout << "DEBUGGING .... entering dot if .....
" << endl;
cout << "DEBUGGING .... m is ..... "<< m <<
endl;
/* if((m==0) || (m>3))
{
return false;
} */ // this check goes to
default ??
switch(m)
{
case 1:
{
ip_part=k[0];
m=0;
}
case 2:
{
ip_part=10*k[1]+k[0];
m=0;
}
case 3:
{
ip_part=100*k[2]+10*k[1]+k[2];
m=0;
}
default:
{
cout << "DEBUGGING m=.. " << m
<< " end of DEBUGGING " ;
return false;
}
}
if((ip_part<1) || (ip_part>254))
{
return false;
}
}
else if((tempString[i]!=DOT) || (tempString[i]<'0') ||
(tempString[i]>'9'))
{
cout << "this is tempString ... " <<
tempString[i] << endl;
cout << " DEBUGGING entering the else if
sequence " ;
return false;
}
}
return true;
}

int main(void)
{
GenericIpAddress myIp("127.45.43.132");

if(myIp.isIpValid()==true)
cout << "IP IS ABSOLUTELY VALID "<< endl << endl ;

return 0;
}
The problem is in the isIpValid function . The object myIp has to
create a valid Ip but it doesn't . If you examine the output of the
program you will find out that the function enters both if statements
, not only the if((tempString[i]>'0') && (tempString[i]<'9')) but the
else if((tempString[i]!=DOT) || (tempString[i]<'0') ||
(tempString[i]>'9')) as well which is something strange as i believe
i check every condition . Can you help me ???

(Sorry for my english .... )


Jul 22 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Andrew escribió:
switch(m)
{
case 1:
{
ip_part=k[0];
m=0;
}
case 2:
{
ip_part=10*k[1]+k[0];
m=0;
}
case 3:
{
ip_part=100*k[2]+10*k[1]+k[2];
m=0;
}
default:
{
cout << "DEBUGGING m=.. " << m
<< " end of DEBUGGING " ;
return false;
}
}
You probably want a break at the end of each case.
else if((tempString[i]!=DOT) || (tempString[i]<'0') || > (tempString[i]>'9'))
You probaly mean:
else if((tempString[i]!=DOT) && ( (tempString[i]<'0') || > (tempString[i]>'9')) )


Regards.
Jul 22 '05 #2

P: n/a

"Julián Albo" <JU********@terra.es> skrev i meddelandet
news:3F***************@terra.es...
Andrew escribió:
switch(m)
{
case 1:
{
ip_part=k[0];
m=0;
}
case 2:
{
ip_part=10*k[1]+k[0];
m=0;
}
case 3:
{
ip_part=100*k[2]+10*k[1]+k[2];
m=0;
}
default:
{
cout << "DEBUGGING m=.. " << m
<< " end of DEBUGGING " ;
return false;
}
}
You probably want a break at the end of each case. else if((tempString[i]!=DOT) || (tempString[i]<'0') || > (tempString[i]>'9'))
You probaly mean:

else if((tempString[i]!=DOT) && ( (tempString[i]<'0') || > (tempString[i]>'9')) )
k[m]=(int)tempString[i];
This will return the ascii value of the digit. You should probarbly use:
k[m] = tempString[i] - '0';
case 2: ip_part=10*k[1]+k[0];
case 3: ip_part=100*k[2]+10*k[1]+k[2];


And add the digits in correct order, and in case 3 the correct digits:

case2: ip_part = 10*k[0]+k[1]
case 3: ip_part=100*k[0]+10*k[1]+k[2];
Jul 22 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.