Isdigit

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?
Please help
Anyone?
Please
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.