Isdigit
Nov 14, 2012 at 9:49pm UTC
I need your help.. really.. please..
I want to create a class which allows only digits to be stored and other character uses will throw in Exceptions
All error checking (bounds checking of indices, etc.) must be handled as exceptions (try, throw, catch). And the test program has to show that All exceptions work..
So what i have is this much:
DigitString.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
#ifndef DIGIT_STRING_H
#define DIGIT_STRING_H
#include "WCS_String.h"
#include <iostream>
#include <cctype>
using namespace std;
class DigitString: public WCS_String
{
public :
DigitString ();
DigitString (const DigitString &);
DigitString (const WCS_String &);
~DigitString ();
DigitString & Concat (const DigitString &);
DigitString & Concat (const WCS_String &);
bool SetAt (char , int );
DigitString & operator = (const DigitString &);
DigitString & operator = (const WCS_String &);
private :
char & operator [] (int );
};
inline DigitString & DigitString::Concat (const DigitString & D)
{
WCS_String::Concat (D);
return *this ;
}
inline DigitString & DigitString::Concat (const WCS_String & A)
{
WCS_String::Concat (A);
isdigit ();
return *this ;
}
inline bool DigitString::SetAt (char c, int i)
{
return WCS_String::SetAt (isdigit (C), i);
}
inline DigitString & DigitString::operator = (const DigitString & D)
{
WCS_String::operator = (D);
return *this ;
}
inline DigitString & DigitString::operator = (const WCS_String & A)
{
WCS_String::operator = (A);
isdigit ();
return *this ;
}
#endif
DigitString.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#include "DigitString.h"
DigitString::DigitString ()
{
}
DigitString::DigitString (const DigitString & D): WCS_String (D)
{
}
DigitString::DigitString (const WCS_String & A): WCS_String (A)
{
isdigit ();
}
DigitString::~DigitString ()
{
}
So my question is : is the above code right and what i need to remove or add + what should i put in my Main.cpp for this isdigit to work?
Nov 15, 2012 at 12:36am UTC
Please help
Nov 15, 2012 at 12:48am UTC
Anyone?
Nov 15, 2012 at 1:16am UTC
Please
Nov 15, 2012 at 3:16am UTC
class DigitString: public WCS_String { /* ... */ };
Assuming that
WCS_String
allows non-digits, this is a technical blunder.
It violates the Liskov substitution principle:
http://en.wikipedia.org/wiki/Liskov_substitution_principle
1 2 3 4 5 6 7 8
void foo( WCS_String& s ) { s = "lets put some non-digits into it" ; }
int main()
{
DigitString a( "1234" ) ; // ok; all digits
foo(a) ; // substitute object of type DigitString for object of type WCS_String
// and what has happened to the invariant of DigitString?
}
Instead, use either private inheritance or containment. Something like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
#include <string>
#include <cctype>
#include <stdexcept>
typedef std::string WCS_String ;
struct digit_string
{
digit_string( const WCS_String& s ) : str(s) { are_digits(str) ; }
bool set_at( char c, std::size_t pos )
{
if ( !std::isdigit(c) )
throw std::domain_error( WCS_String("non numeral character '" ) + c + "'" ) ;
else str.at(pos) = c ; // std::string will throw if pos is out of range
return true ;
}
digit_string operator = ( const WCS_String& s ) { if ( are_digits(s) ) str = s ; return *this ; }
// etc
friend inline std::ostream& operator << ( std::ostream& stm, const digit_string& s )
{ return stm << s.str ; }
private :
WCS_String str ;
bool are_digits( const WCS_String& s )
{
for ( char c : s ) if ( !std::isdigit(c) )
throw std::domain_error( "non numeral in string '" + s + "'" ) ;
return true ;
}
};
And your test driver would be something like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#include <iostream>
int main()
{
try { digit_string s( "1234X67" ) ; std::cout << s << ": ok\n" ; }
catch ( const std::exception& e ) { std::cerr << "error: " << e.what() << '\n' ; }
try
{
digit_string s( "1234567" ) ; std::cout << s << ": ok\n" ;
s.set_at( '9' , 3 ) ; std::cout << s << ": ok\n" ;
s.set_at( '@' , 3 ) ; std::cout << s << ": ok\n" ;
}
catch ( const std::exception& e ) { std::cerr << "error: " << e.what() << '\n' ; }
// etc ...
}
Topic archived. No new replies allowed.