Do you think you've discovered an error in this book?
Please check the list of errata below to see if we've already addressed the error. If not,
please submit the error via our
Errata Form.
We will attempt to verify your error; if you're right, we will post a correction below.
| Chapter | Page | Details | Date | Print Run |
|
21 |
Page 21: TrialRun.cpp A line is missing from the TrialRun.cpp program shown on page 21. The listing should be as follows:
// TrialRun.cpp
// Our first program
#include <iostream>
using namespace std;
int main()
{
// code as shown in book
}
The missing line is shown in the screenshot on the following page and
is used throughout the rest of the book. 'using namespace std;' allows
routines from the C++ standard library to be incorporated into the
program (in this case 'cout'). The using directive and namespaces are
explained on pages 42 and 85 to 88.
|
17-Sep-98 |
1 |
|
83 |
Page 83: Try It Out - The Scope Resolution Operator
The second sentence of the paragraph introducing the 'Try It Out'
concludes with an erroneous statement. The sentence should simply read
as follows:
However, it's still possible to get at the global variable using the scope resolution operator (::).
Namespaces are discussed in Chapter 2, not Chapter 1. The scope resolution operator is not discussed until Chapter 8.
|
13-Jul-99 |
1 |
|
85 |
Page 85: Namespaces
The second sentence on page 85 should read as follows:
We'll talk further about namespaces, including how to create your own, shortly.
|
14-Jul-99 |
1 |
|
86 |
Page 86: Demonstrating Namespace Names
In exercise 2_08.cpp, the line,
std::cin << value;
should read as follows:
std::cin >> value;
|
28-Sep-98 |
1 |
|
88 |
Page 88 typo
The third sentence on the page should read as follows:
Of course, you would not usually organize a source file in this way
deliberately, but it can arise quite naturally with header files that
you include into a program.
Thanks to Ryan McLaughlin
|
18-May-01 |
1 |
|
137 |
Clarification on use of cin.getline()
Some readers have asked for clarification regarding the use and behavior of cin.getline() as it compares to using the << operator. In particular, a problem can arise when the former is used immediately after the latter.
These two techniques of obtaining input differ in the way they deal
with the carriage return that typically terminates text entered by the
user. Specifically, << doesn't remove the carriage return from the input stream, but cin.getline() does. A potential consequence of this is that when cin.getline() is called after using <<,
it finds the carriage return that's been left in the input buffer and
returns immediately, offering the user no opportunity to provide the
input you were seeking.
If you need to use cin.getline() after using <<, one option available to you is to call cin.ignore() before doing so, as this will remove the stray carriage return from the input buffer.
|
05-Mar-03 |
1 |
|
145 |
Page 145: Hexadecimal Numbers
In Visual C++ 6, unlike Visual C++ 5, hexadecimal numbers are not prefixed by 0x when they appear on screen.
|
29-May-00 |
0 |
|
147 |
Page 147: Terminating a String
appearing between the quotes and terminated with /0 should read appearing between the quotes and terminated with \0
|
29-May-00 |
1 |
|
178 |
Page 178: Missing Bracket
At the bottom of the page, there should be an opening bracket ( between static_cast<int> and 2.0.
|
29-May-00 |
1 |
|
193 |
Missing line of code The code listing on this page is missing a line that was present in the code on p191. The listing should begin:
#include <iostream>
#include <cstdlib>
using namespace std;
|
05-Nov-02 |
1 |
|
217 |
Misleading section on handling memory allocation errors
The section that occupies the majority of this and the following page is misleading. To use the _set_new_handler() function, it's necessary to include the new.h header file in your code, rather than the standard library file new that the book identifies. However, it's also possible to include new, and then to use the standard library function set_new_handler() (note the lack of a leading underscore) instead.
|
24-Feb-03 |
1 |
|
227 |
Page 227: Eliminating Blanks from a String
In the function eatspaces, the return statement is unnecssary.
Enclosing the lines
if(*(str+i) != ' ')
i++;
in curly brackets, i.e.
if(*(str+i) != ' ')
{
i++;
}
will make the code easier to understand, although this is not essential.
|
29-May-00 |
1 |
|
234 |
Page 234: Analyzing a Number
In the final line of the figure at the top of page 234, the factor should be 0.001 (not 0.01, as shown).
|
05-Jan-99 |
1 |
|
238 |
Page 238: Extracting a Substring
The penultimate line of the extract() function on page 238 is superfluous - the program will compile and run with or without it. The exit(1); command ends the program, thus rendering the return pstr; line that follows it redundant. (It removes any need to return from the function at this point.)
|
16-Feb-99 |
1 |
|
241 |
Page 241: Exercise 6-1
In the answer to Exercise 6-1, the variable P[i] in the final line of the function should be enclosed in brackets:
return static_cast<int>(p[i]);
|
05-Jan-99 |
1 |
|
272 |
Page 272: A Complete WindowProc() Function
The WINAPI specifier in both the WindowProc() function definition on
page 272 and its prototype on page 273 should be replaced with
CALLBACK, so that they read as follows:
long CALLBACK WindowProc(...)
|
04-Feb-99 |
1 |
|
308 |
Page 308: const keyword
The function header double volume() should be followed by the keyword const.
|
26-May-00 |
1 |
|
310 |
Page 310: Arrays of Class Objects The constructor definition in Exercise 8_10 should read:
CBox(double lv, double bv = 1.0, double hv = 1.0): m_Length(lv), m_Breadth(bv), m_Height(hv)
{
cout << endl << "Constructor called.";
}
The code shown in the book causes ambiguity over which constructor
should be called, giving rise to the compiler errors described on page
295. In the code in the book, both constructors could be used to
initialize the data members of the CBox objects in the array boxes. If
a default value for lv is not supplied in the first constructor, the
compiler knows it cannot use that constructor for the initialization
and so uses the default constructor.
|
24-Sep-98 |
1 |
|
312 |
Page 312: Counting Instances The constructor definition in Exercise 8_11 should read:
CBox(double lv, double bv = 1.0, double hv = 1.0): m_Length(lv), m_Breadth(bv), m_Height(hv)
{
cout << endl << "Constructor called.";
objectCount++;
}
The code shown in the book causes ambiguity over which constructor should be called. A more detailed explanation can be found in the erratum for page 310.
|
25-Sep-98 |
1 |
|
320 |
Page 320: Exercises 8-2 and 8-3
The model answers to Exercises 8-2 and 8-3 use destructors, which aren't covered until the next chapter.
|
05-Jan-99 |
1 |
|
330 |
Page 330: DisplayMessage() function definition If you try to incorporate the code snippets shown on page 330 into Exercise 09_02 the program will not compile. This is because the ShowIt() function is defined as having a void return type but the << operator cannot take a right hand operand of type void.
The DisplayMessage() function should, therefore, be defined as follows:
void DisplayMessage(CMessage localMsg)
{
cout << endl << "The message is: ";
localMsg.ShowIt();
return;
}
Thanks to Sasa Bosnjak.
|
17-Sep-98 |
1 |
|
343 |
Page 343: comment The second comment in the code at the bottom of the page should read
//Check addresses. If equal, return a reference to the 1st operand.
|
12-Jun-00 |
1 |
|
343 |
Page 343: motto1 The line Motto1 = *pMess; should read motto1 = *pMess; where motto1 starts with a lower case 'm'. |
29-May-00 |
1 |
|
347 |
Page 347: Overloading the Addition Operator
The second comment (// Class definition at global scope) wraps on to the next line. "scope" is not a command!
|
05-Jan-99 |
1 |
|
351 |
Page 351: Defining a Class Template A semicolon is missing from the default constructor at the top of the page. The default constructor should read as follows:
CSamples()
{
m_Free = 0;
}
Also, the comment on the penultimate line of the class listing wraps onto the next line. m_Values is not a command, it is part of the comment on the previous line, which should read as follows:
int m_Free; // Index of free location in m_Values
|
04-Feb-99 |
1 |
|
363 |
Page 363: Analyzing CBox Objects
At the
top of page 363, the return statement includes a static_cast with a
bracket instead of an angled bracket. The line should read as follows:
return static_cast<int>(...code as shown in book...);
|
05-Jan-99 |
1 |
|
374 |
Page 374: Adding Global Functions
The second parameter of the CBox
multiply operator should be a reference. The next-to-last line in the
list of declarations for global box operators should read as follows:
CBox operator*(int n, const CBox& aBox);
|
05-Jan-99 |
1 |
|
374 |
Using Visual C++ Macros
When you follow
the book's instructions for running macros, you may find yourself
confronted by a blank Macro dialog box. Should this happen to you,
there's a relatively easy fix.
With no files open in Visual C++6, you need to click on
Tools | Macro. Then, in the Macro dialog box that appears,
you have to click on Options | Loaded Files. Finally, in the
Add-ins and Macro Files tab of the Customize dialog box that appears,
you need to enable the Sample macro by clicking on the check box. After
you've closed the dialog, you can follow the book's directions to run
the macro.
|
05-Mar-03 |
1 |
|
380 |
Page 380: Summary
In the final line of the first bullet point, "default constructor" should read, "default destructor".
|
16-Feb-99 |
1 |
|
386 |
Page 386: Deriving Classes from a Base Class
The destructor in listing 10_01-02 should not have a semicolon after the closing curly bracket.
|
05-Jan-99 |
1 |
|
391 |
Page 391: Constructor Operation in a Derived Class
The first line of the first paragraph in the section entitled
"Constructor Operation in a Derived Class" should read as follows:
Although we said that the base class constructor is not inherited in the derived class, it still exists for the base part of the derived class object.
|
05-Jan-99 |
1 |
|
404 |
Friend Classes The fourth line on page 404 reads:
friend CCarton;
It should read as follows:
friend class CCarton;
|
21-Jun-00 |
1 |
|
420 |
Page 420: Calling the Wrong Destructor
In the paragraph below the screenshot, the third sentence should read as follows:
For the other objects, the correct destructor calls occur with the
derived class destructor being called first, followed by the base class
destructor.
|
23-Feb-99 |
1 |
|
443 |
Page 443: Making the CCalculator Class Safe to Use
Due to what appears to be a bug in the ClassWizard, using the Add
Member Function dialog to add the assignment operator to the
CCalculator class will not work. An implementation will be provided in
the Calculator.cpp file but no declaration will be added to the class
definition in Calculator.h.
Consequently you shouldn't bother with the Wizard and should add
the declaration manually. The declaration should be placed in the
private section of the class, as shown on page 445.
As stated in the book, no implementation is needed - if you've used the
Wizard to add the assignment operator function you should delete the
implementation that the Wizard produces.
|
02-Oct-98 |
1 |
|
444 |
Page 444: Starting the Calculator The declaration of the copy constructor for the CCalculator class should be
in the private section of the class (as stated in the text) and not in
the public section (as shown in the class definition).
The correct class definition is shown below:
class CCalculator
{
public:
void Run() const;
CCalculator();
virtual ~CCalculator();
private:
CCalculator(const CCalculator& rCalculator);
CCalculator& operator=(const CCalculator& rhs);
CKeyboard* m_pKeyboard;
CLogicUnit* m_pLogicUnit;
CDisplay* m_pDisplay;
};
|
02-Oct-98 |
1 |
|
444 |
Page 444: implementation
In later editions, the sentence, "If
you have used ClassWizard to add the operator function, you will need
to delete the implementation as it is added automatically", is added to the first paragraph on the page.
|
13-Jun-00 |
1 |
|
450 |
Page 450: Declaration of CLogicUnit::OnDigit()
The function CLogicUnit::OnDigit() should be declared as:
void OnDigit(const int& digit);
This amendment to the function's parameter also applies to the
declaration of OnDigit() shown on page 452 and its implementation shown
on page 453.
|
05-Jan-99 |
1 |
|
451 |
Page 451: Logic Unit Registers Table
Some of the values shown in the table do not accurately reflect the workings of the code.
When the '+' is entered the values held in the registers should be as follows:
Display = 1.5
Multiply = 1.5
Add = 1.5
When '5' is entered the values should be:
Display = 5
Multiply = 1.5
Add = 1.5
When 'Enter' is pressed, the values should be:
Display = 6.5
Multiply = 1.5
Add = 6.5
Thanks to Sasa Bosnjak.
|
17-Sep-98 |
1 |
|
453 |
Page 453: OnDigit function
The OnDigit function should be declared as follows. void OnDigit(const int& digit);
|
09-Jun-00 |
1 |
|
454 |
Page 454: The CRegister Class
In the CRegister class, the OnDigit() function should be declared as follows:
void OnDigit(const int& digit);
|
23-Feb-99 |
1 |
|
457 |
Page 457: Handling a Digit in CRegister
The parameter of the function CRegister::OnDigit() should be:
const int& digi
|
05-Jan-99 |
1 |
|
458 |
Page 458: Declaration of m_bBeginValue
The CRegister member variable m_bBeginValue should be declared as bool (as stated in the text) rather than int (as shown in the code).
|
13-Jan-99 |
1 |
|
459 |
Page 459: operator+ function
In the comments in the definition of the operator+ function, R1 and R2 should be replaced by reg1 and reg2.
|
09-Jun-00 |
1 |
|
465 |
Page 465: CLogicUnit contructor
The second line of code at the bottom of the page should end m_pCalc(pCalc) with an underscore rather than a hyphen.
|
12-Jun-00 |
1 |
|
470 |
Page 470: Register Contents Table Some of tde values and actions shown in tde table do not accurately reflect the workings of the code.
tde lower part of tde table should appear as follows:
| Key |
Action |
m_DisplayReg |
m_AddReg |
m_MultiplyReg |
| + |
m_DisplayReg * m_MultiplyReg |
3 |
1 |
6 |
| |
Copy m_MultiplyReg to M_DisplayReg |
6 |
1 |
6 |
| |
m_DisplayReg + m_AddReg |
6 |
7 |
6 |
| |
Copy m_AddReg to m_DisplayReg |
7 |
7 |
6 |
| 4 |
Store in m_DisplayReg |
4 |
7 |
6 |
| Enter |
m_DisplayReg + m_AddReg |
4 |
11 |
6 |
| |
Copy m_AddReg to m_DisplayReg |
11 |
11 |
6 |
|
17-Sep-98 |
1 |
|
471 |
Page 471: Completing the CDisplay Class
The incomplete declaration of the CRegister class (which you are told
to add) is missing from the contents of the file Display.h. The
following line should be placed immediately above the incomplete
declaration of CCalculator:
class CRegister;
|
05-Jan-99 |
1 |
|
484 |
Page 484 Missing Semicolon
First 3 lines of the function declaration should read:
int main()
{
long* pnumber = NULL;
long number1 = 55;
long number2 = 99;
Thanks to Clinton Hess
|
22-Feb-01 |
1 |
|
487 |
Page 487: typing error
On the final line "withhandling" should read "with handling".
|
09-Aug-00 |
1 |
|
512 |
Page 512: Functions Checking the Free Store
In the second sentence of the section entitled Functions Checking the Free Store, ctrdbg.h should read crtdbg.h.
|
12-Jun-00 |
1 |
|
521 |
Page 521: Preprocessor symbol
The preprocessor symbol _NDEBUG should be _DEBUG.
|
05-Jan-99 |
1 |
|
535 |
Page 535: MFC Hierarchy Diagram
The first sentence of the second paragraph on page 535 should read as follows:
Each arrow in the diagram points to a derived class from its base class.
|
08-Jul-99 |
1 |
|
618 |
Page 618 Typing error
The final sentence on the page should read:
. Create a new header file and add the following skeleton code:
Thanks to David Sneed
|
22-Feb-01 |
1 |
|
621 |
Page 621: comment wrap
In the code at the top of the page, a comment, // Get the bounding rectangle for an element, has wrapped to the next line.
|
12-Jun-00 |
1 |
|
662 |
Page 662 Error in code The code snippet presented on this page should only contain one call to SetROP2 to
ensure that curves are drawn with solid rather than dotted lines.
The code should therefore read as:
void CSketcherView::OnMouseMove(UINT nFlags, CPoint point)
{
//Define a Device Context object for the view
CClientDC aDC(this);
if((nFlags & MK_LBUTTON) & (this == GetCapture()))
Thanks to Peter Schoellkopf
|
22-Feb-01 |
1 |
|
690 |
Page 690: Highlighting Elements
An
extra argument has been included in the constructor for the line
object. The final argument should not be added until the next chapter,
so the constructor declaration should read as follows:
CLine(const CPoint& Start, const CPoint& End, const COLORREF& Color);
|
20-Oct-98 |
1 |
|
717 |
Page 717: Adding Pen Widths to the Elements
The constructor declaration in the CLine class should read as follows:CLine(const CPoint& Start, const CPoint&
End, const COLORREF& Color, const int& PenWidth);
|
20-Oct-98 |
1 |
|
785 |
Page 785: Writing Your Own DLLs
There are two references to, 'DLLs which don't involve MFC' - a topic which is not covered in the book. The first is in the bulleted list on page 785 and the second is in the 'Writing DLLs' section on page 792.
|
26-Oct-98 |
1 |
|
792 |
Page 792: Writing DLLs
The last sentence in the section entitled Writing DLLs
which reads "Finally, we will cover how to write plain Windows
DLLs which do not involve MFC at all." should be deleted.
|
12-Jun-00 |
1 |
|
882 |
Expediting the Update Currently the database will not be updated with changed records on exiting the routine. This can be acheived by inserting the following line:
void CDBSampleView::OnEditorder()
{
if( m_pSet->CanUpdate() )
{
try
{
if (m_UpdateMode)
{
m_EditCtrl.SetWindowText("Edit Order");
m_Abort.ShowWindow(SW_HIDE);
UpdateData(true); //Added Line
m_pSet->Update();
}
else
{
...
Thanks to Scott Weber
|
01-Dec-00 |
1 |
|
883 |
Page 883: Controlled Updating In order to correctly cancel an update operation, an extra line needs to be added to the definition of OnCancel().
The extra line should read:
UpdateData(FALSE);
It should be inserted after the line that cancels the update operation so that the definition of OnCancel() reads as follows:
void COrderDetailsView::OnCancel()
{
m_pSet->CancelUpdate();
UpdateData(FALSE);
m_EditCtrl.SetWindowText("Edit");
m_CancelCtrl.ShowWindow(SW_HIDE);
m_QuantityCtrl.SetReadOnly(m_UpdateMode);
m_DiscountCtrl.SetReadOnly(m_UpdateMode);
m_UpdateMode = !m_UpdateMode;
}
UpdateData() is explained on page 898.
Thanks to Christopher Hutchinson.
|
22-Oct-98 |
1 |
|
902 |
Page 902: Selecting Products for an Order
In the definition of InitializeView(), m_CompanyName should be
replaced with m_CustomerName. The fourth line in the body of the
function should read:
m_CustomerName = pDoc->m_Order.m_ShipName;
|
29-Oct-98 |
1 |
|
932 |
Page 932: Implementation of OnUpdate() The implementation of the OnUpdate() member function of
CWrxContainerView is missing from Chapter 22. The following text should
have been added immediately before the 'Setting the Tracker Style'section:
We need to override the default implementation of the OnUpdate()
function in order to make use of the hint information passed in the
second and third parameters. Add this function to the CWrxContainerView
class using ClassWizard, giving the return type as void and the name as
OnUpdate(CView* pSender, LPARAM lHint, CObject *pHint). The
implementation is shown below:
void CWrxContainerView::OnUpdate(CView *pSender, LPARAM lHint, CObject *pHint)
{
if(lHint==HINT_UPDATE_ITEM)
{
//We need to pass a rectangle to InvalidateRect() for the item
//that takes account of the tracker
CRectTracker tracker; //The tracker
SetupTracker((CWrxContainerItem*)pHint, &tracker); //...setup for the item
CRect rect;
tracker.GetTrueRect(rect); //Get the tracker rectangle
InvalidateRect(rect); //and invalidate that.
}
else
{
InvalidateRect(0);
}
}
|
03-Dec-98 |
1 |
|
945 |
Page 945: Drawing the Document In the OnUpdate() function, pHint is cast to CElement instead of CElement*. The line should, therefore, read as follows:
CRect aRect = static_cast<CElement*>
(pHint)->GetBoundRect();
|
26-Oct-98 |
1 |
|
982 |
Page 982: Testing the Control
In the third paragraph on page 982, the menu option that you should select is:
Edit | Insert New Control
|
16-Feb-99 |
1 |
|
1045 |
Page 1043: Definition of OnDraw() The contents of the file OurConstants.h should be as shown on pages 975 and 978. The full listing is given below:
//Definition of constants
#ifndef __OURCONSTANTS_H__
#define __OURCONSTANTS_H__
const int STOP = 101;
const int GO = 103;
const int READY_TO_STOP = 104;
const COLORREF RED = RGB(255, 0, 0);
const COLORREF ORANGE = RGB(200, 100, 0);
const COLORREF GREEN = RGB(0, 255, 0);
const COLORREF GRAY = RGB(100, 100, 100);
#endif
|
29-Oct-98 |
1 |
|
1051 |
Page 1051: Adding the Signal to the Control
The CSignal constructor should include the following line (which is added by the ATL COM AppWizard):
m_bWindowOnly = TRUE;
|
29-Oct-98 |
1 |
|
1051 |
Page 1051: Drawing the Control
In the OnDraw function definition at the bottom of the page, the first line should read
HRESULT OnDraw(ATL_DRAWINFO& di)
Inthe same function definition, the static_cast is inappropriate.
Therefore the first line in the body of the function should read
RECT& rc = *(RECT*)di.prcBounds; // Get control rectangle
|
29-Oct-98 |
1 |
|
1053 |
Page 1053: Definition of StartSignal()
In the definition of StartSignal(), the call to SetSignalState() should
be a call to SetState(). The second line in the body of the function
should, therefore, read as follows:
m_TrafficSignal.SetState(m_bStartRed ? STOP : GO);
|
29-Oct-98 |
1 |
|
1054 |
Page 1054: Starting and Stopping the Signal
In the first paragraph on page 1054, SetTimer() is described as having three arguments. In fact, the version of SetTimer() used here only has two arguments, as shown in the StartSignal() function definition. The two arguments are the timer ID and the time interval in milliseconds.
|
29-Oct-98 |
1 |
|
1062 |
Page 1062: screenshot
The screenshot should reflect the fact that the states are 101, 103, 104 (not 101, 102, 103).
|
12-Jun-00 |
1 |
|
1065 |
Page 1065: Appendix A
The keywords shown below should be included in the list:
export
wchar_t
The following are not Visual C++ keywords:
bad_cast
bad_typeid
type_info
|
29-Oct-98 |
1 |
|
1075 |
Page 1075: Answer to exercise 2-4
The answer to exercise 2-4 should have only one of the arguments in the
division cast to a double, as described in the text but not as shown in
the line of code. The line of code should read as follows:
double aspect = static_cast<double>(width)/height;
The code as shown in the book will produce the answer 1 (when dividing
640 by 480). This is because both width and height are integer
variables and therefore the result of (width/height) will be an integer
also; the nearest integer to the actual result of 1.333 being 1. Only
when the division has been performed is the result cast to a double
(i.e. the integer 1 is cast to the double 1.0).
In the correct version only width is cast to a double. Width is then
divided by the integer height, producing a result that is a double (in
this case 1.333).
|
25-Sep-98 |
1 |
|
1111 |
Page 1111 - Ex14-4 The code solution given for Exercise 14-4 should read as follows:
void CSketcherDoc::OnUpdateColorBlack(CCmdUI* pCmdUI)
{
//Set menu item checked if the current color is black
pCmdUI->SetCheck(m_Color==BLACK);
//Set upper case for a selected item, lower case otherwise
if(m_Color == BLACK)
pCmdUI->SetText("BLACK");
else
pCmdUI->SetText("black");
}
Thanks to Vincent Hand
|
27-Jul-01 |
1 |
|
1135 |
Page 1135: Solution to exercise 21-3
When you create the recordset class, CEmployeeSet,
based on the employee table, the wizard will create the class with
member variables corresponding to all the fields in the table. As you
can see from the constructor shown on page 1135, most of these members
have been deleted using ClassWizard, leaving only the 3 fields we need.
Care should be take when deleting fields from a recordset class not to
delete the key field(s).
In the second paragraph on page 1136, the text reads "To control the list box, add another variable to CCustomerView". Note that you should use ClassWizard to add this variable, m_EmployeeCtrl.
As well as adding the member variable to the header file (as shown in
the code snippet), the wizard will automaically add the following line
to the DoDataExchange() method in the .cpp file:DDX_Control(pDX, IDC_EMPLOYEENAME, m_EmployeeCtrl);Remember that this function controls the exchange of values between data members and dialog controls.
Note that in the code shown for CCustomerView::OnInitialUpdate() at the bottom of page 1136, a call to SetNewOrderID() is shown. This is superfluous, as the method has already been called from CMainFrame::SelectView().
In the first paragraph on page 1138, the text states "the listbox handler we added to CCustomerView ...". Note that you need to add this handler at this point using ClassWizard.
|
26-Nov-98 |
1 |