2012年2月22日 星期三

Exercise #16


Purpose
The purpose of this assignment is
  • To give you practice in using the C++ input/output classes and file I/O.
  • To give you practice in program planning, design and development.
  • To solve a practical "real-world" problem.
Program Description
This program will track a portfolio consisting of three mutual funds over a ten year period. You will invest $10,000 exactly 10 years prior to the date that you run your program. You will use actual mutual fund historical data that you will download as input files to your program.

Requirements
Your must use a main() that is similar to the sample below. The "real work" should not be performed in main().
Your program output file should "logically" match that of the sample output below. You will probably use different mutual funds and run your program for different dates. You must display the initial investment data for your portfolio, the value of the portfolio 5 years ago, 3 years ago, 1 year ago, at the beginning of the year and the current value.
You should turn in the program listing and your output file.
Your solution must contain at least 3 classes, one of which is a "date" class. The "date" class must contain an overloaded insertion operator that "prints" a "date" in an "mm/dd/yy" format.
You are to use the actual downloaded mutual fund historical data. You may not edit this data.
You are to use the closing prices of the mutual on the date of interest. If that date is not a "market open" date, then you must backup and get the previous closing price of the fund.
You must invest at least $3000 in each fund.

References
Yahoo finance page:  http://finance.yahoo.com/
You can look up mutual fund data by entering the "ticker" symbol next to the Get Quotes button at the top of the page. On the mutual fund "Summary" page, use the "Historical Prices" link on the left side of the page to get the history. On the "Historical Prices" page, use the "Download to Spreadsheet" link to download the mutual fund history to a file. Note, the download file is named table.csv, so you need to give it a unique name, since you'll need three different mutual fund history files.

You can find lots of good funds on these sites:
http://bloomberg.com/apps/data?pid=invest_mutualfunds
http://www.kiplinger.com/investing/funds/kip25/tables/index.php
http://www.smartmoney.com/top25funds/http://www.morningstar.com/allanalyses/analysesLists.html?type=FO&fsection=all2000&lpos=Commentary
http://moneycentral.msn.com/investor/research/fundwelcome.asp?Funds=1

Assumptions
Assume that the input data is reliable, that dates and the mutual fund closing prices are valid.
Assume that you do not have access to dividends or capital gains. There is no reinvestment. You give all that money to charity (or the teacher).

Suggestions
Allow 4-12 hours to solve this problem. You will need more time for program planning and analysis than the previous assignments.

Extra Credit
The student with the most valuable portfolio using "today's" closing prices will receive 2 extra credit points. In the event of a tie, only 1 point will be awarded. Remember, actual data must be used for this, but you are free to run the program on different days. By completing the program early, you can pick a day with a good market close.

Sample main()

int main()
{
    Date today;
    Portfolio myPortfolio(today.nYearsBefore(10));
    myPortfolio.addFund("VTSMX",3333.33f,"c:/deanza/data/vtsmx.csv");
    myPortfolio.addFund("VGTSX",3333.33f,"c:/deanza/data/vgtsx.csv");
    myPortfolio.addFund("VBMFX",3333.34f,"c:/deanza/data/vbmfx.csv");
    ofstream fout("c:/deanza/data/ass9.out");
    myPortfolio.report(today,fout);
    return 0;
}

Sample Program Output File

Mutual Funds                        VTSMX       VGTSX       VBMFX       Total      

Initial Investment   06/06/99     3333.33     3333.33     3333.34    10000.00
Initial Shares                    132.380     358.808     572.739    

Value 5 years ago    06/06/04     3243.31     3519.91     4547.55    11310.77
Value 3 years ago    06/06/06     3828.43     5098.67     4874.01    13801.11
Value 1 year ago     06/06/08     4314.27     6562.61     5544.11    16420.98
Value on January 1st 01/01/09     2953.40     3950.48     5715.93    12619.81
Value today          06/06/09     3060.63     4345.17     5738.84    13144.64

Exercise #15


Read in the input file below and produce the report shown.

Input file

John,Doe,123456789,20,21,22,23,16,19,16,50,75
Francisco,Washington,987654321,10,0,20,13,18,19,16,30,70
Tom,Nguyen,111111111,18,23,24,25,17,22,20,38,90
Victoria,Black,333333333,22,21,22,21,20,22,21,45,64
Sally,Seinfield,444444444,17,12,19,23,24,12,11,34,94
Sylvester,De La Rosa,555555555,25,25,24,20,25,25,21,44,80
George,O'Neill,666666666,21,12,3,14,21,14,17,45,99
Sylvia,Smart,777777777,20,21,22,23,24,20,25,44,78
Judy,Yang,888888888,16,19,22,24,25,20,25,45,100
Charles,Black,222222222,20,21,22,22,21,25,16,40,86


                            CIS27 Class Grades Report

Student Name          --- SSN ---  ---- Lab Grades ----  Mid  Fin  Pts   Perct  G
--------------------  -----------  -- -- -- -- -- -- --  ---  ---  ---   -----  -
Doe, John             123-45-6789  20 21 22 23 16 19 16   50   75  246   82.0%  B
Washington, Francisc  987-65-4321  10  0 20 13 18 19 16   30   70  196   65.3%  D
Nguyen, Tom           111-11-1111  18 23 24 25 17 22 20   38   90  260   86.7%  B
Black, Victoria       333-33-3333  22 21 22 21 20 22 21   45   64  238   79.3%  C
Seinfield, Sally      444-44-4444  17 12 19 23 24 12 11   34   94  234   78.0%  C
De La Rosa, Sylveste  555-55-5555  25 25 24 20 25 25 21   44   80  269   89.7%  B
O'Neill, George       666-66-6666  21 12  3 14 21 14 17   45   99  243   81.0%  B
Smart, Sylvia         777-77-7777  20 21 22 23 24 20 25   44   78  257   85.7%  B
Yang, Judy            888-88-8888  16 19 22 24 25 20 25   45  100  280   93.3%  A
Black, Charles        222-22-2222  20 21 22 22 21 25 16   40   86  253   84.3%  B


Program requirements
  • Use C++ input/output techniques and file I/O, no stdio. You should declare one ifstream and one ofstream object.
  • Create at least 3 classes:
    • Name consists of a first and last name.
    • StudentInfo consists of a Name, SSN, 7 lab grades, a midterm, final, and whatever else you want.
    • Class consists of an array of StudentInfo or an array of StudentInfo pointers
  • The rules for calculating points and grades are exactly like the 1st assignment or what was stated on the course syllabus. Remember to discard the lowest lab grade, but not the last one.
  • Use the same input file shown. You may get a copy of the data file in the ATC if you do not want to type it in.
  • Produce exactly the report, with the same spacing, formatting and text. Turn in a copy of the report file along with your program listing.
  • If you are unsure of any program detail, ask the instructor for clarification.

Extra Credit (1 point each)
  • Sort the report by Name (major sort by last name, minor sort by first name)
  • Handle a missing lab score instead of a 0.  Use this record for Francisco Washington: Francisco,Washington,987654321,10,,20,13,18,19,16,60,140
  • Change the lab grades in the input file to octal, but print them out as hexadecimal.

Exercise #14


This assignment will give you practice with C++ input/output classes and file I/O. Use the following program specifications and use the following main() to test your program. You should use the WordFile and the Dictionary classes described below, and any others you wish.

Here is the WordFile class. Write the 4 member functions. Add any others you desire. The getNextWord() function should place the "next word to be read" in the buffer argument and return it. If getNextWord() fails, it should return a null pointer. 

class WordFile {
  private:
    fstream File;
  public:
    WordFile(const char* filename);
    void addWord(const char* word);
    void goToTopOfFile();
    char* getNextWord(char* buffer);
};

The Dictionary class should contain two members, an fstream object and an unsigned int, which stores the number of words in the Dictionary. The Dictionary constructor should use a WordFile& argument. This constructor should read the WordFile's file into memory. Use dynamic memory allocation to temporarily store the words, so they can be sorted. After sorting, write them out to the new Dictionary file and clean up.

Add four more members functions to the Dictionary class, getNumWords(), getDictionarySizeInBytes(), getMiddleWord() and find(). The function, getMiddleWord(), should return the word that's in the middle of the file. That is, if the file is 100 bytes, then the function should return the word that begins on or before byte 50.

Add a friend operator<<() to the Dictionary class. This function should print out the Dictionary.

Use the main() below for the final testing of your program. It, and the sample program run should give you more insight to the program. If you do not complete the program, turn in only the functions and the parts of the program that run, along with the output. Do not turn in a program that does not run.

Test your code thoroughly after you complete each function. Do not attempt the Dictionary class until you WordFile class is complete.

int main() {
  WordFile Words("wordfile.txt");
  char buffer[MaxWordSize];
// Read words into the Word file
  cout << "Enter words for the Word file (“quit” to stop)\n";
  while (cin.getline(buffer,MaxWordSize)&&strcmp(buffer,”quit”))
    Words.addWord(buffer);
  Dictionary Webster(Words);
// Print the Dictionary
  cout << Webster << endl;
// Print the Dictionary size
  cout << "Dictionary size = " << Webster.getDictionarySizeInBytes() << endl;
// Print the word in the middle of the dictionary
  cout << "The middle word is " << Webster.getMiddleWord(buffer) << endl;

// Search for words in the Dictionary
  cout << "Enter words to search for in the Dictionary (“\quit\” to stop)\n";
  cin.clear();
  while (cin.getline(buffer,MaxWordSize) && strcmp(buffer,"quit")) {
    cout << buffer << " is ";
    if (Webster.find(buffer)) cout << "definitely ";
    else cout << "NOT ";
    cout << "in the Dictionary\n";
  }
  return 0;
}

******  Sample Run  ******

Enter words for the Word file (enter "quit" to stop)
chimpanzee
whale
bald eagle
tiger
zebra
mouse
horse fly
mountain goat
baboon
quit
Dictionary Words:
        baboon
        bald eagle
        chimpanzee
        horse fly
        mountain goat
        mouse
        …

Dictionary size = 86            <- Note this could be a different size
The middle word is ???            <- this may vary
Enter words to search for in the Dictionary ("quit" to stop)
elephant
elephant is NOT in the Dictionary
goat
goat is NOT in the Dictionary
baboon
baboon is definitely in the Dictionary
zebra
zebra is definitely in the Dictionary
mountain goat
mountain goat is definitely in the Dictionary
dog
dog is NOT in the Dictionary
quit

Exercise #13


This assignment will give you practice in producing formatted output using C++ input/output classes. Create a class consisting of an int, an unsigned, a long, a short, and a double. Generate random numbers to assign to the members. Print 20 lines of output using the class. Each line should be printed exactly as illustrated below. Of course, the numbers will not match since they are random. The output specifications are:

The first column contains the int member left justified displayed in octal.
The second column contains the unsigned member left justified displayed in hex.
The third column contains the long member left justified displayed in decimal.
The fourth column contains the short member left justified displayed in hex.
The fifth column contains the double member right justified.
The sixth column contains the double member right justified.
The seventh column contains the double member right justified.

The integer types should be printed in a field of width 9, the doubles using a width of 12. Make sure you match the base indicators and the precision of the doubles. 

Note:  for the scientific output shown in the last two columns, your compiler will print the exponent as either a 2-digit or 3-digit number, but not both. You cannot control this. You will have to figure out a way to massage the double value to produce one of the scientific outputs. 

62436    0X22E8   2888     1889         426.0986  4.261e+002   4.26e+02
72062    0X29AF   7884     106c           5.1463  5.146e+000   5.15e+00
47262    0X68E8   19107    5a62           0.9017  9.017e-001   9.02e-01
31237    0X1A6C   29243    2cce          39.5479  3.955e+001   3.95e+01
13020    0X33FD   17339    459d           0.0789  7.890e-002   7.89e-02
74524    0X7E67   8056     5b9e           0.6746  6.746e-001   6.75e-01
45040    0X1842   21039    596            1.3779  1.378e+000   1.38e+00
14051    0X1995   1452     408c           1.8856  1.886e+000   1.89e+00
12706    0X24CE   17308    6bfe           0.0308  3.078e-002   3.08e-02
37534    0X66C5   21689    6e05           0.9871  9.871e-001   9.87e-01
15311    0X2AC5   15003    a87            3.0408  3.041e+000   3.04e+00
56020    0X8D1    3278     200b           0.0388  3.877e-002   3.88e-02
67351    0X23A1   12797    41d1           1.9757  1.976e+000   1.98e+00
76410    0X3908   21582    5a36           0.4780  4.780e-001   4.78e-01
13472    0X42C1   7242     7193           4.8966  4.897e+000   4.90e+00
35644    0X5EDA   16355    350a           2.4271  2.427e+000   2.43e+00
16706    0X7E32   23414    360d           1.0195  1.019e+000   1.02e+00
62433    0X3CC4   26845    667b           1.1618  1.162e+000   1.16e+00
16543    0X1ABC   3301     5eac           0.6685  6.685e-001   6.69e-01
57772    0X5E7E   28111    51be           9.0853  9.085e+000   9.09e+00

Exercise #12


This assignment will give you practice with inheritance and polymorphism.

  1. Create an abstract Solid base class. It should consist of:
    • data members to represent the (x,y,z) coordinates of a solid in 3D space
    • at least one constructor
    • a function that displays the coordinates of a Solid object as (x,y,z)
    • pure virtual functions that:
    • return the volume of the object
      return the surface area of the object
      return the type of the solid
      print "specialized" details about a Solid object (i.e. radius, height, width, …)
    • a non-virtual function that prints all information about a Solid object (it should call the 5 functions listed above)
  2. Derive from the Solid class the following classes:
    • RectangularSolid
    • This class should have three members: length, width, and height.
    • Sphere
    • This class should have one member, radius.
    • Cylinder
    • This class should have two data members, radius and height.
    • Cone
    • This class should have two data members, radius and height.
  3. From the RectangularSolid class, derive a Cube class. It does not have any data members. It only needs a constructor, a type function, and a "print details" function.
You may need the following formulas for this assignment


Use the following main() as a final test of your program:
int main() {
    RectangularSolid        Rec(1.,2.,3.,4.,5.,6.);
    Sphere            Sph(1.,2.,3.,4.);
    Cylinder            Cyl(1.,2.,3.,4.,5.);
    Cone            Con(1.,2.,3.,4.,5.);
    Cube            Cub(1.,2.,3.,4.);
    Solid*            ps;

    // Rectangular Solid test
    ps = &Rec;
    ps->print();

    // Sphere test
    ps = &Sph;
    ps->print();

    // Cylinder test
    ps = &Cyl ;
    ps->print();

    // Cone test
    ps = &Con ;
    ps->print();

    // Cube test
    ps = &Cub ;
    ps->print();
    return 0;
}

******  Program Output  ******

I am a rectangular solid located at (1,2,3)
length=4 width=5 height=6
volume=120 surface area=148

I am a sphere located at (1,2,3)
radius=4
volume=268.082 surface area=???

I am a cylinder located at (1,2,3)
radius=4 height=5
volume=??? surface area=???

I am a cone located at (1,2,3)
radius=4 height=5
volume=??? surface area=???

I am a cube located at (1,2,3)
side=4
volume=64 surface area=???

Exercise #11


This assignment will give you practice with inheritance and polymorphism.

Create the following classes:

GeometricObject:    This is the base class for the other four classes. It should have two protected data members, x and y (coordinates). The class should have the following member functions:
    GeometricObject()    // ctor
    getX()        // accessor function
    getY()        // accessor function
print()
    describeYourself()
    length()
    area()

    All member functions should be const member functions, except the constructor. describeYourself(), length(), and area() functions should be pure virtual functions. The print() function should display the line of output shown below, like
    GeometricObject: 0x????? - location = (x,y)

point    Is derived from GeometricObject and has no data members. Its length() and area() functions should return 0.0.

line    Is also derived from GeometricObject and has two point data members, p1 and p2.  Its constructor must initialize the x,y members of the GeometricObject class. The (x,y) coordinates of a line should be the midpoint of p1 and p2 (take the average of the x coordinates and the average of the y coordinates). Its area() function should return 0.0, but the length() function should return the distance between the two points. Use the formula:

 circle    Is also derived from GeometricObject and has one data member, a double, radius. The constructor should have a point argument and a double argument. The point argument is used to initialize the (x,y) coordinates of the GeometricObject base and the double to initialize the radius.  The length() function should return the circle's circumference and the area() function . r2.

triangle    Is also derived from GeometricObject and has 3 point data members, p1, p2, and p3. Its constructor should have three (point) arguments, to initialize the data members. It also needs to initialize the GeometricObject's (x,y) coordinates. The (x,y) coordinate for a triangle should be the average of its x coordinates and the average of its y coordinates. Add three private member functions, side1(), side2(), side3() to the class. They should each return a double length of a side. For example, side1() should return the length of the side that is opposite point p1. These functions will be useful for the length() and the area(). The length() should return the triangle's perimeter. Use the following formulas for the area of a triangle:


Use the main() below to test your program. The output should give you an indication of what is expected.

int main(void)
{
  int i;
  Point P(0,0), Q(3,0), R(3,4);
  P.DescribeYourself();
  Line L(Q,R);
  L. DescribeYourself ();
  Circle C(P,3);
  C. DescribeYourself();
  Triangle T(P,Q,R);
  T. DescribeYourself();

// polymorphism testing
  GeometricObject* Obj[6];
  Obj[0] = new Point(2,1);
  Obj[1] = new Point(8,1);
  Obj[2] = new Point(5,5);
  Obj[3] = new Line(P,Q);
  Obj[4] = new Circle(P,2.0);
  Obj[5] = new Triangle(P,Q,R);

  for (i = 0; i < 6; i++) Obj[i]-> DescribeYourself();

  for (i = 0; i < 6; i++) delete Obj[i];

  return 0;
}

******  Program Output  ******

GeometricObject: 0x6a0c4 - location = (0,0)
I am a point

GeometricObject: 0x6a060 - location = (3,2)
I am a line
Length=4

GeometricObject: 0x6a038 - location = (0,0)
I am a circle
Area=28.2743  circumference=18.8496

GeometricObject: 0x69fd4 - location = (2,1.33333)
I am a triangle
Area=6  permeter=12

GeometricObject: 0x6c160 - location = (2,1)
I am a point

GeometricObject: 0x6c180 - location = (8,1)
I am a point

GeometricObject: 0x6c1a0 - location = (5,5)
I am a point

GeometricObject: 0x6b100 - location = (?,?)
I am a line
Length=?

GeometricObject: 0x6c1c0 - location = (?,?)
I am a circle
Area=??????  circumference=??????

GeometricObject: 0x6e100 - location = (?,?)
I am a triangle
Area=?  permeter=??

Extra Credit (1 point0) Add a constructors to the circle class, so that you can create a circle:
using a point and a line - the first point is the center, the circle is tangent to the line.

2012年2月21日 星期二

Exercise #10


This assignment will give you practice with overloaded operator functions.
Create a Date class to represent calendar dates. 
The class should contain the following members:
  • Three unsigned short data members to represent day, month, and year.
  • A static const unsigned short 12-element array containing the number of days in each month.
  • A constructor that initializes the three unsigned short members.
It should contain the following overloaded operator member functions:
  1. A ! operator that prints a Date object using the format mm/dd/yy.
  2. A prefix ++ operator that adds a day to a Date object. It should return the object by reference.
  3. A postfix ++ operator that adds a day to a Date object. It should return the object by value.
  4. A prefix -- operator that subtracts a day from a Date object. It should return the object by reference.
  5. A binary + operator with an unsigned short argument. This function should add a number of days to a date object. Use call(s) to the prefix ++ operator in your function definition. It should return a Date object by value.
  6. A binary - operator with an unsigned short argument. This function should subtract a number of days from a date object. Use call(s) to the prefix -- operator in your function definition. It should return a Date object by value.
  7. A += operator with with an unsigned short argument. This function should add a number of days to a date object. Use call(s) to the prefix ++ operator in your function definition. It should return a Date object by reference.
  8. A == operator that determines if two Date objects are equal. This function should return a bool.
  9. A != operator that determines if two Date objects are not equal. This function should return a bool.
  10. A > operator that determines if the "current" Date object is greater than another Date object. One Date object is greater than another Date object if it occurs after the other object. For example, "03/15/02" > "12/25/01". This function should return a bool.
  11. A binary – operator with a const Date& argument. This function should determine the number of days between two Dates. The function should return an int. For example, "01/03/02" – "12/30/01" . 4 and "12/30/01" – "01/03/02" . -4.
Appropriate member functions should be defined as const member functions

Assumptions
It is not necessary to make leap year corrections for this assignment. Assume that February always has 28 days and that a year is exactly 365 days.
A year value between 0 and 49 represents the years 2000 to 2049. A value between 50 and 99 represents the years 1950 to 1999.

Write a main() that demonstrates each of the overloaded member functions. Your output should demonstrate the validity of each function. 

Exercise #9


Create a Money class consisting of an unsigned int and an unsigned short data member, dollars and cents. You may assume that all money values are non-negative. Add the following member functions:
  1. A constructor with two default arguments, an unsigned int and an unsigned short. The arguments should initialize the dollars and cents members. Since both arguments have default values (both 0), this constructor also serves as a default constructor.
  2. A constructor with a double argument. The double must be used to initialize both the dollars and cents. For example, an argument of 1.75 should assign 1 to the dollars and 75 to the cents. Round off cents to the second decimal place, so 5.55555 would set the dollars to 5 and the cents to 56.
  3. A copy constructor.
  4. An overloaded !(unary) operator that serves as a print function. It should print the dollars and cents with a leading dollar sign and a decimal point separating the dollars and cents. Make sure you are able to print the following values:  $1.03, $10.00, $0.01, $1234.56, and $0.00.
  5. An overloaded + (unary) operator that "reduces" Money. For example, if you passed 5 and 150 into the first constructor, you would want to use this function to change the Money object to have dollars = 6 and cents = 50. This function should return Money by reference.
  6. An overloaded < (binary) operator that tests two Money objects to see if the first is less than the second. This function should return a bool.
  7. An overloaded == (binary) operator that tests two Money objects to see if the first is equal to the second. This function should return a bool.
  8. An overloaded + (binary) operator that adds two Money objects and returns the sum by value(Money). Make sure your logic can handle $2.56+$5.67 and $5.63+$0.37.
  9. An overloaded - (binary) operator that subtracts two Money objects and returns the difference. It should return a Money by value. If you try to subtract a larger Money from a smaller one, print an error message and have the function return $0.00. (0 dollars and 0 cents).
  10. An overloaded * (binary) operator with a double argument. This permits you to multiple a Money object by a double, For example, $4.29*67.3. It should return a Money by value.
  11. An overloaded += operator that adds more Money to a Money object and returns the result by reference. For example, M1 += M2;  (this should change M1).

Divide your final program into three files: a header file for your Money class, a source file for your Money methods, and another source file for main(). Write you own main() and thoroughly test all functions. Make sure your main() demonstrates calls to each member function. 

Exercise #8


This assignment will give you practice writing constructors and destructors, static data members, static member functions, friend functions, and overloaded operator functions. The purpose of the program is to write a simple game involving dice. You are to create the three classes described below.  Use the main() provided. The sample output should give you additional information about the program requirements.

Create a Die class with the following specifications:
  • One private data member, an unsigned short, value.
  • A private member functions, roll() that generates a random number and assigns it to value. You can use the expression, rand() % 6 + 1, to generate the random number.
  • Add an overloaded operator < private member function that can be used to compare the value of two Die objects.   
  • Name the class Dice as a friend of the Die class. Remember to forward declare the Dice class.
  • Reminder:  all members of the Die class are private. Access must be controlled through the Dice class.
Create a Dice class with the following specifications:
  • One data member, dice, a five element array of Die.
  • A roll() function that calls the Die roll() to assign values to the dice array. This function should call the following sort() function.
  • A private member function sort() that will sort the dice array.
  • A min() function that returns the minimum of the dice array.
  • A sum() function that returns the sum of the dice array.
  • A max() function that returns the maximum of the dice array.
  • A average() function that returns the average of the dice array, rounded to the nearest integer.
  • A median() function that returns the median of the dice array.
  • A averageOfHighAndLow() function that returns the average of the maximum and minimum values of the dice array. "Round up" this average.. For example, if the high is 6 and the low is 1, your function should return 4 (that's 3.5 rounded up). The min(), sum(), max(), average(), median() and averageOfHighAndLow() functions should return an unsigned short.
  • An overloaded! Operator that prints the value of the 5 dice and the points for the roll.
  • An overloaded+ operator that can be used to determine the point value of the dice array. The points are equal to the average + median + averageOfHighAndLow for the roll of the dice.
Create a Player class with the following specifications:
  • Private data members, char* name and unsigned short score.
  • Two static unsigned short data members, NumberOfPlayers and PlayerNumberWhoseTurnItIs.
  • A constructor and destructor.
  • Two accessor functions, getName() and getScore() to return the name and the score.
  • A roll() function that calls the Dice roll(), prints the value of the dice (hint:  use the ! operator of the Dice class) and returns the points for the roll(hint: use the Dice overloaded operator+).
  • A takeTurn() function that calls the roll() function, adds that turns points to the score and returns the score.
  • A static member function, whoseTurnIsIt(), that returns the PlayerNumberWhoseTurnItIs.
  • A static member function, nextPlayer(), that manages the PlayerNumberWhoseTurnItIs.
  • A static member function, HowManyPlayers() that returns the NumberOfPlayers.
Write one non-class member function, printScores() that prints out the player names and scores as shown the program output.  It should have a Player* argument.

Additional requirements:
  • The game ends when one player scores 100 points.
  • Try to match the program output, except for the random points and scores.
  • Your program should use every function and data member listed.  You should "reuse" a lot of code.
 Use this main():

int main(void) {
  Dice Lucky;
  Player Beatles[4];
  unsigned short PlayerScore = 0;
  printScores(Beatles);
  while (PlayerScore < 100) {
    Player::nextPlayer();
    PlayerScore=Beatles[Player::whoseTurnIsIt()].takeTurn(Lucky);
    printScores(Beatles);
  }
  cout << "The winner is "
       << Beatles[Player::whoseTurnIsIt()].getName() << endl;
  return 0;
}

Here is the program output:

Enter player name => John
Enter player name => Paul
Enter player name => George
Enter player name => Ringo
Scores: John 0   Scores: Paul 0   Scores: George 0   Scores: Ringo 0
-------------------------------------------------------------------------
John, you rolled 1 3 5 5 6  - that's 13 points
Scores: John 13   Scores: Paul 0   Scores: George 0   Scores: Ringo 0 
-------------------------------------------------------------------------
Paul, you rolled 1 4 5 5 5  - that's 12 points
Scores: John 13   Scores: Paul 12   Scores: George 0   Scores: Ringo 0 
-------------------------------------------------------------------------
George, you rolled 1 2 3 4 4  - that's 9 points
Scores: John 13   Scores: Paul 12   Scores: George 9   Scores: Ringo 0 
-------------------------------------------------------------------------
Ringo, you rolled 1 2 2 4 5  - that's 8 points
Scores: John 13   Scores: Paul 12   Scores: George 9   Scores: Ringo 8 
-------------------------------------------------------------------------
John, you rolled 1 2 3 3 4  - that's 9 points
Scores: John 22   Scores: Paul 12   Scores: George 9   Scores: Ringo 8 
-------------------------------------------------------------------------
Paul, you rolled 2 3 4 6 6  - that's 12 points
Scores: John 22   Scores: Paul 24   Scores: George 9   Scores: Ringo 8 
-------------------------------------------------------------------------
George, you rolled 2 3 3 4 6  - that's 11 points
Scores: John 22   Scores: Paul 24   Scores: George 20   Scores: Ringo 8 
-------------------------------------------------------------------------
Ringo, you rolled 1 2 3 5 6  - that's 10 points
Scores: John 22   Scores: Paul 24   Scores: George 20   Scores: Ringo 18 
-------------------------------------------------------------------------
John, you rolled 1 2 3 3 4  - that's 9 points
Scores: John 31   Scores: Paul 24   Scores: George 20   Scores: Ringo 18 
-------------------------------------------------------------------------
Paul, you rolled 2 2 3 3 3  - that's 9 points
Scores: John 31   Scores: Paul 33   Scores: George 20   Scores: Ringo 18 
-------------------------------------------------------------------------
George, you rolled 2 3 3 6 6  - that's 11 points
Scores: John 31   Scores: Paul 33   Scores: George 31   Scores: Ringo 18 
-------------------------------------------------------------------------
Ringo, you rolled 1 2 4 6 6  - that's 12 points
Scores: John 31   Scores: Paul 33   Scores: George 31   Scores: Ringo 30 
-------------------------------------------------------------------------
John, you rolled 1 2 3 4 5  - that's 9 points
Scores: John 40   Scores: Paul 33   Scores: George 31   Scores: Ringo 30 
-------------------------------------------------------------------------
Paul, you rolled 1 2 3 4 5  - that's 9 points
Scores: John 40   Scores: Paul 42   Scores: George 31   Scores: Ringo 30 




George, you rolled 1 2 2 4 6  - that's 9 points
Scores: John 98   Scores: Paul 99   Scores: George 91   Scores: Ringo 87 
-------------------------------------------------------------------------
Ringo, you rolled 1 2 4 4 6  - that's 11 points
Scores: John 98   Scores: Paul 99   Scores: George 91   Scores: Ringo 98 
-------------------------------------------------------------------------
John, you rolled 2 2 3 4 5  - that's 10 points
Scores: John 108   Scores: Paul 99   Scores: George 91   Scores: Ringo 98 
-------------------------------------------------------------------------
The winner is John


Exercise #7


This assignment will give you practice working with classes, constructors, static data member, static member functions, and friend functions. The goal of this assignment is to create a partial model of a population system, emulating the aging and dying of a population, but unfortunately not the birth process. But, maybe that's fortunate for the programmer

Program requirements:
  • Create the three classes described below.
  • Use the main() function included.
  • Your output should look like that shown below.
  • Your program must be divided into multiple files. Each class should be defined in a separate header file and the member functions for each class should be in a separate source file.  main() should also be in a separate file. Your program should consist of at least 7 files. Print each file on a separate page.
Class Descriptions
The date class is used to represent calendar dates. As a minimum, the class must contain:
  • 3 unsigned int data members to represent month, day, and year
  • a default constructor (use the same one from assignment 4)
  • a constructor that takes 3 unsigned ints as arguments
  • an increment function that adds 1 day to the date (you can use the same one from assignment 3. For determining ages, you can assume that a year is 365.25 days long.
  • a display() _pass() function that adds a random number of days to a date. The random number sfunction that displays the date in the mm/dd/yy format
  • a let_timehould be between 1 and 365. You will be using this function to add days to the (global) TODAY date. Hint:  you might use the random number to call the increment() function repeatedly.
  • Declare the human class as a friend of the date class.
  • Declare the function, int  difference_between_2_dates(date,date) as a friend of the date class.
The human class must contain at least:
  • 3 data members:
  • char    name[32]
    date    birthday
    bool    alive
  • 2 static data members
  • static human*    oldest_human
    static unsigned long    number_of_living_humans
  • a constructor:    human(const char* n,const date& b)
  • necessary accessor functions
  • a function, age() that returns a human's age in years
  • a die() function (you know what that means)
  • a display() function
  • a static member function that assigns the appropriate human* to the oldest_human.
  • a static member function that returns the number_of_living_humans
  • Declare the function void population::display() const as a friend of the human class.
The population class must contain:
  • Two data members:
    • human**    people
    • const unsigned long    original_size
  • A private member function:     determine_oldest() that "sets" the oldest_human
  • A constructor
  • A destructor
  • A display() function
  • An examine_population() function that takes a look at the population, calls the following roll_the_dice() function for each "living" human.  If roll_the_dice() returns a number greater than .5, the human should "die".
float roll_the_dice(unsigned short age)
{
    return (float) age*(rand()%100)/10000.;
}

Assumptions
  • All humans were "born" in the last century.
  • Use the difference_between_2_dates() function so that it always returns a positive value. That is, you should always subtract the older date from the newer date.
  • Use a population size of 20 for the final testing of your program.
Hints and Suggestions
  • If you are new to working with multiple files, keep your program as one file until you get it working, then try to split it into multiple files.
  • Declare TODAY as a global variable.  To do this, enter:
  • date TODAY;
    in your main() source file and declare it as an extern in the date header file, like this:
    extern date TODAY;
  • Create a global array of names that you can use in the population constructor, like this:
  • char* NAMES[] = {"Fred","Sam","Sally","George","Sue","Mary","Bill",...};
  • Do not work with a population size of 20 until you are sure that your program is working. Use a small population, like 4 or 5.
The main() function

int main()
{
    srand(time(0));            // seed the random number generator
    population World(POPULATION_SIZE);
    cout << "Today is ";
    TODAY.display();
    cout << endl;
    World.display();

    // let time pass until half of the world's population dies
    do
{
        TODAY.let_time_pass();   
        World.examine_population();    // record deaths, find oldest
    } while (human::get_number_of_living_humans() > POPULATION_SIZE/2);

    cout << "Today is ";
    TODAY.display();
    cout << endl;
    World.display();
    return 0;
}

Sample Output

Today is 11/22/03

Allen was born on 9/15/04 is 99
Catherine was born on 11/1/62 is 41
Naihui was born on 10/16/56 is 47
Gayatri was born on 9/26/24 is 79
Bin was born on 5/12/28 is 75
Evan was born on 5/2/82 is 21
Sandy was born on 3/8/50 is 53
Sridevi was born on 4/26/85 is 18
Tanya was born on 3/26/32 is 71
Jing was born on 9/18/25 is 78
Haiying was born on 7/24/75 is 28
Rose was born on 1/21/25 is 78
Nisha was born on 5/8/72 is 31
Hnin was born on 3/14/68 is 35
Adeline was born on 8/17/57 is 46
Chen Wei was born on 8/8/19 is 84
Joe was born on 7/6/86 is 17
Bob was born on 11/26/33 is 69
Mary was born on 7/8/41 is 62
Sue was born on 4/7/80 is 23
The oldest living person, Allen is 99 years old.

4/9/04 Allen died at the age of 99
4/9/04 Chen Wei died at the age of 84
4/9/04 Bob died at the age of 70
9/16/04 Sandy died at the age of 54
9/16/04 Tanya died at the age of 72
9/16/04 Rose died at the age of 79
9/16/04 Mary died at the age of 63
1/10/05 Bin died at the age of 76
8/5/05 Gayatri died at the age of 80
8/5/05 Jing died at the age of 79
Today is 8/5/05

Catherine was born on 11/1/62 is 42
Naihui was born on 10/16/56 is 48
Evan was born on 5/2/82 is 23
Sridevi was born on 4/26/85 is 20
Haiying was born on 7/24/75 is 30
Nisha was born on 5/8/72 is 33
Hnin was born on 3/14/68 is 37
Adeline was born on 8/17/57 is 47
Joe was born on 7/6/86 is 19
Sue was born on 4/7/80 is 25
The oldest living person, Catherine is 42 years old.

Exercise #6


This assignment will give you practice writing constructors and destructors, static data members and static member functions, and friend functions.  You are to create a Dictionary application to store words. You will allocate memory dynamically to store each word. Before you store each word, you need to check in the Dictionary to make sure that the word is not already in the Dictionary. Follow all directions listed below.

Create a Word class with the following:
  • The class should contain two data members:
    • a char* data member, ptrWord.
    • a static int member, WordCount that contains the number of words added to the Dictionary.
  • Three constructors:
    • A default constructor that allocates memory for a one element char array, initialized to '\0'. (this will not get used in your final program)
    • A constructor with a const char* argument. This constructor should allocate memory dynamically to store the argument. This is the constructor that will be used to store your words.
    • A copy constructor. (this will not get used in your final program)
  • A destructor to perform the necessary release of memory.
  • A print() function the displays the word.  It should be a const member function and define it inline.
  • Another const member function, GetWord() that returns the char*, ptrWord.
  • A static member function, GetWordCount() that returns the WordCount.

Create a Dictionary class with the following:
  • One data member, words, that is a 100 element array of pointers to Word.
  • A default constructor that initializes the 100 Word pointers to 0.
  • A destructor that releases memory for each Word added to the Dictionary.
  • A const member function, FindWord(char*), that returns a pointer to the Word if it is in the Dictionary, otherwise a null pointer.
  • A function, AddWord(char*), that is used to add words to the Dictionary. AddWord should allocate memory dynamically for each word to be added. (Hint: a Word constructor should help you out here) Use the FindWord() function to make sure that you are not adding a word into the Dictionary that is already there.  AddWord should return an int, 1, if the word is successfully added, otherwise 0.
  • A print() const member function that prints out all words stored in the Dictionary.
  • A friend function, void print(const Dictionary&, int n), that prints out the nth word in the Dictionary.

Use the following main() to test your program:

int main (void)
{
  Dictionary Webster;
  int i;
  char temp[25];
  cout << "Enter 10 words separated by whitespace\n";
  for (i = 0; i < 10; i++) {
    cin >> temp;
    Webster.AddWord(temp);
  }
  Webster.print();
  cout << "The fifth word is " ; print(Webster,4);
  cout << "There are " <<Word::GetWordCount()<<" words in the Dictionary\n";
  return 0;
}

The output should look something like this:

Enter 10 words separated by whitespace
dog cat bird mouse goat horse dog pig fish Dog
* Error: duplicate word: dog
The Dictionary contains:
dog
cat
bird
mouse
goat
horse
pig
fish
Dog
The fifth word is goat
There are 9 words in the Dictionary


Extra Credit (1 point each)
Do not attempt this unless you first complete the required assignment and totally understand what you did.
  • Modify the Dictionary print() function to print the words out in sorted order.
  • Implement the Dictionary class as a linked list. The Word class will need to be modified to add a Word* member. You will have to modify/add other Word class member functions to treat it as a "node". The main() function should not have to be changed. The Dictionary class member function arguments should stay the same, but the code should change.
Use Example 5-9 as a guide for this assignment.

2012年2月20日 星期一

Exercise #5


Exercise #5

This assignment will give you practice writing constructors and working with a multiple file application. Use the Point and Line header and source files from example 4-12 to complete this assignment. You are to create a Circle class consisting of:
  • Two data members, a Point representing the center of the Circle and a double for the radius.
  • A print() member function that displays Circle data as shown in the output on the next page. Your output should have the exact format as shown.
  • The following ten Circle constructor functions:
    • A default constructor the creates a unit Circle at the origin. That is, center (0,0) and radius 1.
    • A constructor with one double argument. The argument should be used for the radius. The center is assumed to be at the origin.
    • A constructor with two double arguments. The arguments should be used for x-y coordinates of the center. The radius is assumed to be 1.
    • A constructor with a Point and a double argument. The Point should be assigned to the center and the double to the radius. Pass the Point by reference to const.
    • A constructor with three double arguments. The first two doubles should be used for the x-y coordinates of the center. The third double represents the radius.
    • A constructor with two Point arguments. The first Point is the center, and the second represents a Point on the circle. Both points should be passed by reference (to const).
    • A constructor with a Point and a Line argument. The Point is the center. The Circle is tangent to the line. Assume that the Point does not lie on the Line. Pass the arguments by reference.
    • A constructor with one Line argument.  The Line represents the diameter of the Circle.
    • A constructor with a Circle argument and a double argument.  The Circle will be concentric to the argument’s Circle with the double radius.
    • A copy constructor.

Additional requirements:
  • Use the main() provided on the next page.
  • Use the files ex4-12p.h, ex4-12p.cpp, ex4-12lh, and ex4-12l.cpp for the Point and Line class definitions and member functions.
  • Create a multi-file application.  Put your Circle class definition in a separate header file and the Circle member function definitions in a separate source file.
  • Turn in only the Circle header file, the Circle member function source file, main() as a separate source file and the program output.
  • Use constructor initializers in every constructor, even though it is not required. This will help you become familiar with the syntax.

Use this main() for the program.

int main(void)
{
    Point P(2.3,1.3), Q(3.4,4.5), R(3.1,4.9);
    Line L(P,Q);
    Circle C1;
    C1.print();
    Circle C2(3.5);
    C2.print();
    Circle C3(2.6,3.5);
    C3.print();
    Circle C4(P,5.5);
    C4.print();
    Circle C5(1.1,2.3,5.8);
    C5.print();
    Circle C6(P,Q);
    C6.print();
    Circle C7(R,L);
    C7.print();
    Circle C8(L);
    C8.print();
    Circle C9(C8,5.0);
    C9.print();
    Circle C10(C9);
    C10.print();

    return 0;
}


Your output should look like this:

center=(0,0) radius=1
center=(0,0) radius=3.5
center=(2.6,3.5) radius=1
center=(?,?) radius=?
center=(?,?) radius=?
center=(?,?) radius=?
center=(?,?) radius=?
center=(?,?) radius=?
center=(?,?) radius=?
center=(?,?) radius=?

Exercise #4


Exercise #4

Create a date class consisting of:
  • 3 private unsigned int data members:  month, day, and year.
  • 5 constructors, as described below
  • a destructor, as described below
  • a print() function
  • an increment() function

Use the following global variables:

const char* const Months[12] = {"January","February","March","April","May", "June","July","August","September","October","November","December"};
const unsigned CurrentYear = 2009;
// DaysPerMonth - non-const so that changes can be made for leap year
unsigned DaysPerMonth[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};

Constructors:
  • The default constructor should look something like this:
  • // The default constructor returns the current system date
    date::date() {
    time_t timer = time(0);
    tm* NOW = localtime(&timer);
    month = NOW->tm_mon+1;  // NOW->tm_mon is current month#-1
    day = NOW->tm_mday;
    year = NOW->tm_year + 1900;
    }
  • The time_t and tm types and the time() and localtime() functions are defined in the ANSI C header file, ctime. Review the documentation for these types and functions.
  • The second constructor should have 3 unsigned arguments, the third argument is default = CurrentYear. The 3 arguments should be assigned to the month, day, and year members respectively. Observe the assumption listed below concerning 2-digit years. This constructor should be able to take a 2-digit or a 4-digit year.
  • The third constructor should take a char* argument of the form "mmddyy" or "mm/dd/yy". The argument should be parsed and respective values assigned to the month, day, and year members. Observe the assumption listed below concerning 2-digit years.
  • The fourth constructor should take a single unsigned int argument, the day of the year for the current year. For example, date(25) is January 25, 2009 and date(364) is December 30, 2009.
  • The fifth constructor is the copy constructor.

The destructor should call the print() function to display the date that is being destructed.

The print() function, with a default int argument, should display dates with a format mm/dd/yy or Month d, yyyy or ddMONyy, depending on the value of the argument. Note the uppercase in the 3rd format.  Note: mm/dd/yy is the default format.

The increment() function should add 1 day to any date.  This function must work for leap years.  The rules for leap years are:
  • A leap year occurs in every year that can be divided evenly by four, except the years that mark the even hundreds, such as 1500.
  • The only century years that are leap years are those that can be divided evenly by 400, such as 1600 and 2000.

Assumptions:
  • For the constructors, any 2-digit reference to a year is to be interpreted as follows:  1) assume any two-digit year reference < 50 refers to years between 2000 and 2049.  2) assume any two-digit year reference >= 50 refers to years between 1950 and 1999.  For example, 02/04/94 means February 4, 1994, and 02/04/49 means February 4, 2049.
  • Assume date values for month, day, year, and day of the year are correct. You do not have to perform error checking on these values. 

Use this main() to test your program and redirect your output to a file.  Turn in the output file with your program listing.

int main()
{
  int i;
  date D1;
  date D2(9,19,00);
  date D3(7,15,49);
  date D4(1,10);
  date D5("010148");
  date D6("10/01/59");
  date D7(2,26,1936);
  date D8(2,26,2000);
  date D9(2,26,1900);
  date D10(2,26,1999);
  date D11(25);
  date D12(364);
  date D13(D10);
  D1.print(); D1.print(1); D1.print(2);
  D2.print(); D2.print(1); D2.print(2);
  D3.print(); D3.print(1); D3.print(2);
  D4.print(); D4.print(1); D4.print(2);
  D5.print(); D5.print(1); D5.print(2);
  D6.print(); D6.print(1); D6.print(2);
  D7.print(); D7.print(1); D7.print(2);
  D8.print(); D8.print(1); D8.print(2);
  D9.print(); D9.print(1); D9.print(2);
  D10.print(); D10.print(1); D10.print(2);
  D11.print(); D11.print(1); D11.print(2);
  D12.print(); D12.print(1); D12.print(2);
  D13.print(); D13.print(1); D13.print(2);
  cout << "5 days after "; D7.print(1);
  for (i = 1; i <= 5; i++) D7.increment(); D7.print(1);
  cout << "5 days after "; D8.print(1);
  for (i = 1; i <= 5; i++) D8.increment(); D8.print(1);
  cout << "5 days after "; D9.print(1);
  for (i = 1; i <= 5; i++) D9.increment(); D9.print(1);
  cout << "5 days after "; D10.print(1);
  for (i = 1; i <= 5; i++) D10.increment(); D10.print(1);
  cout << "35 days after "; D1.print(1);
  for (i = 1; i <= 35; i++) D1.increment(); D1.print(1);
  return 0;
}

******  Output  ******

05/01/09                    - today’s date
May 1, 2009
01MAY09
09/19/00
September 19, 2000
19SEP00
07/15/49
July 15, 2049
15JUL49
01/10/02
January 10, 2002
10JAN02
01/01/48
January 1, 2048
01JAN48
10/01/59
October 1, 1959
01OCT59
02/26/36
February 26, 1936
26FEB36
02/26/00
February 26, 2000
26FEB00
02/26/00
February 26, 1900
26FEB00
02/26/99
February 26, 1999
26FEB99
01/25/02
January 25, 2002
25JAN02
12/30/02
December 30, 2002
30DEC02
02/26/99
February 26, 1999
26FEB99
5 days after February 26, 1936
March 2, 1936                <- you figure it out
5 days after February 26, 2000
March ?, 2000                <- you figure it out
5 days after February 26, 1900
March ?, 1900                <- you figure it out
5 days after February 26, 1999
March ?, 1999                <- you figure it out
35 days after May 1, 2009
? ?, 2009
date destructed: 02/26/99
date destructed: 12/30/02
date destructed: 01/25/02
date destructed: 03/03/99

Exercise #3


Exercise #3

This assignment is a continuation of the exercise 2. The requirements for this assignment are the same as exercise 2. You are to convert the student struct to a class and make the four functions,  getStudentData(), checkStudentData(), calculateFinalGrade(), and printStudentData(), members of your student class.

Make sure you complete the following steps for this assignment:
  • Convert student to a class.  The data members should be private. The three functions, getStudentData(), calculateFinalGrade(), and printStudentData(), should be public members functions.  checkStudentData() should be private.
  • Add a fifth function to the class - void DeleteName(void). This function should handle the delete for the lastname member.
  • printStudentData() should be a const member function.
  • Make DeleteName() an implicit inline function.
  • In main(), prompt the user for the number of students to process. Dynamically allocate the memory for the student objects.
  • Run your code with at least 4 student objects that demonstrate adequate testing of your program. 

Exercise #2


Exercise #2

Write a complete C++ program that makes use of the student struct and main() shown below. The program should read in the student data from the keyboard, calculate the final grade and print the student data for two (or more) test cases. 

Your program should meet the following requirements:
  • Use the student struct with the indicated members.
  • You should write at least four functions, getStudentData(), checkStudentData(), calculateFinalGrade(), and printStudentData(). Each of these functions should take a student struct argument, passed by reference.
  • Your getStudentData() function should allocate memory dynamically for the last name. This memory should be released in main() before your program ends.
  • checkStudentData() should be called by getStudentData(). It should verify the accuracy of the entered data. The ssn should be 9 numeric digits, the labs grades  must have a value between 0 and 25, the midterm between 0 and ??1, and the final between 0 and ???1. If the entered data is incorrect, you may exit the program or ask the user to re-enter the data.
  • The calculateFinalGrade() function should reflect the policies used to determine points and the final grade for the course. Remember to discard the lowest lab grade, but not the last lab.
  • Your program should produce output similar to that shown on the next page. You must submit your output along with a program listing.
  • Do not include a disk or email your solution.

struct student
{
  char* lastname;
  char ssn[10];
  int  lab_grade[NumLabGrades1];
  int  midterm;
  int  final;
  int total_points;
  char final_grade;
};


int main(void)
{
    student Me, You;
    getStudentData(Me);
    calculateFinalGrade(Me);
   
    getStudentData(You);
    calculateFinalGrade(You);
    printStudentData(Me);
    printStudentData(You);

…        <- something goes here

    return 0;
}


**************************  Sample Run #1  *****************************

Enter the last name => Smith
Enter social security number => 123456789
Enter 9 lab grades (separated by a space) => 25 20 18 20 19 18 16 22 19
Enter midterm grade => 65
Enter final grade => 114
Thanks!

Enter the last name => Nguyen
Enter social security number => 987654321
Enter 9 lab grades (separated by a space) => 19 18 17 16 15 14 13 12 11
Enter midterm grade => 55
Enter final grade => 77
Thanks!

Name: Smith
SSN: 123456789
Lab grades: 25 20 18 20 19 18 16 22 19
Midterm: 65
Final: 114
Total Points: ???        - you figure this out
Final grade: ?         - you figure this out

Name: Nguyen
SSN: 987654321
Lab grades: 19 18 17 16 15 14 13 12 11
Midterm: 55
Final: 77
Total Points: ???     - you figure this out
Final grade: ?         - you figure this out

**************************  Sample Run #2  *****************************

Enter the last name => Doe
Enter social security number => 345678901
Enter #1 lab grades (separated by a space) => 11 12 11 12 11 12 …1
Enter midterm grade => 81
Enter final grade => 88
Thanks!

Invalid midterm 81.  Exiting...

Exercise #1


Exercise #1

Use the Date struct, the MonthName array, the function prototypes, the main() and the output below to complete the following program. Make sure that you use C++ ANSI standard header files. Try to match the output exactly. Turn in your entire program and the output.

struct Date
{
    unsigned short month;
    unsigned short day;
    unsigned short year;
};

const char* MonthName[12] = {"January","February","March","April","May",
"June","July","August","September","October","November","December"};

void InputDate(Date*);
void Print1(Date);
void Print2(Date);
void Print3(Date);

int main()
{
    Date FirstDay, FinalDay, HoliDay;
    InputDate(&FirstDay);
    InputDate(&FinalDay);
    InputDate(&HoliDay);
    Print1(FirstDay);
    Print2(FirstDay);
    Print3(FirstDay);
    Print1(FinalDay);
    Print2(FinalDay);
    Print3(FinalDay);
    Print1(HoliDay);
    Print2(HoliDay);
    Print3(HoliDay);
    return 0;
}

******  Program Output  ******

Enter month day year (separated by spaces) => 1 13 2005
Enter month day year (separated by spaces) => 1 1 2005
Enter month day year (separated by spaces) => 12 14 2005
01/13/05
January 13, 2005
13JAN05
01/01/05
January 1, 2005
01JAN05
12/14/05
December 14, 2005
14DEC05

Compile Commands


Microsoft Visual C++ 2008

cl ex8-13.cpp –EHsc

Note: executable name is ex8-13.exe

GNU gxx version 3.10b (for DOS)

g++ ex8-13.cpp -o grep.exe –Wall

******  Sample Program Execution  ******

C:\deanza\examples>grep system *.cpp
ex8-13.cpp[25]                          system_command_status;
ex8-13.cpp[61]  // system() allows you to issue operating system commands
ex8-13.cpp[62]  system_command_status = system(command);
ex8-13.cpp[64]  // check the status of the system command
ex8-13.cpp[65]  if (system_command_status == -1) {
ex8-13.cpp[66]          cerr << "Error with system command: " << command << endl;
ex8-13.cpp[128]         // Issue system erase command
ex8-13.cpp[129]         system_command_status = system(command);
ex8-13.cpp[131]         // status system command
ex8-13.cpp[132]         if (system_command_status == -1) {
ex8-13.cpp[133]                 cerr << "Error with system command: " << command << endl;
all2htm.cpp[65]                 status = system(command);
Found 12 occurrence(s) in 96 file(s)

C:\djgpp\include> \deanza\examples\grep access *.h
dpmi.h[148] int __dpmi_get_descriptor_access_rights(int _selector);                        /* LAR instruction  */
dpmi.h[149] int __dpmi_set_descriptor_access_rights(int _selector, int _rights);                        /* DPMI 0.9 AX=0009 */
io.h[37] #define sopen(path, access, shflag, mode) \
io.h[38]        open((path), (access)|(shflag), (mode))
unistd.h[76] int                access(const char *_path, int _amode);
unistd.h[125] /* additional access() checks */
Found 6 occurrence(s) in 60 file(s)

Note:  this next sample run has quoted arguments for the command. The first argument allows you to search for more than one word in the file. The second argument is quoted, because the GNU executable version wanted wildcard arguments quoted.

C:\deanza\examples>grep "virtual function" "*.*"
EX7-15.CPP[33]        virtual double area(void) const = 0;           // pure vir
tual function
EX7-15.CPP[34]   virtual double girth(void) const = 0;  // pure virtual function

Found 2 occurrence(s) in 124 file(s)

C++ File I/O


Class/Template Descriptions

basic_ifstream<>    class template derived from basic_istream<>. Defines file streams used for input.

    ifstream    basic_ifstream class for char type
    wifstream    basic_ifstream class for wchar type


basic_ofstream<>    class template derived from basic_ostream<>. Defines file streams used for output.

    ofstream    basic_ofstream class for char type
    wofstream    basic_ofstream class for wchar type


basic_fstream<>    class template derived from basic_iostream<>. Defines file streams used for both input and output.

    fstream    basic_fstream class for char type
    wfstream    basic_fstream class for wchar type

basic_ifstream<> members

basic_ifstream();

explicit basic_ifstream(const char* filename, ios_base::openmode mode = ios_base::in);

void close();

bool is_open();

void open(const char* filename, ios_base::openmode mode = ios_base::in);

basic_ofstream<> members

basic_ofstream();

explicit basic_ofstream(const char* filename, ios_base::openmode mode = ios_base::out);

void close();

bool is_open();

void open(const char* filename, ios_base::openmode mode = ios_base::out);

basic_fstream<> members

basic_fstream();

explicit
basic_fstream(const char* filename, ios_base::openmode mode = ios_base::in | ios_base::out);

void close();

bool is_open();

void open(const char* filename, ios_base::openmode mode = ios_base::in | ios_base::out);

Example 8-9 - Simple File I/O

1      // File: ex8-9.cpp
2     
3      #include <iostream>
4      #include <fstream>
5      #include <cstdlib>
6      using namespace std;
7     
8      int main(void)
9      {
10          ifstream f1("ex8-9.cpp");
11          ifstream f2("nofile");
12         
13          ofstream f3("file.one");
14          fstream f4("iofile");
15         
16          char buff[80];
17         
18          if (!f1) {
19              cout << "Hey, I can't find the \"ex8-9.cpp\" file\n";
20              exit(1);
21          }
22     
23          cout << boolalpha;  // turn on "true"/"false" for cout's bools
24     
25          cout << "f2.rdstate()=" << f2.rdstate() << endl;
26          cout << "f2.fail()=" << f2.fail() << endl;
27          cout << "f2.bad()=" << f2.bad() << endl;
28          if (f2.fail())
29              cout << "Hey, I can't find \"nofile\", but who cares\n";
30          if (f3)
31              cout << "Hey, I've decided to create a \"file.one\" file\n";
32     
33          f1 >> buff;
34          cout << buff << endl;
35          f3 << "Have a nice day\n" << endl;
36     
37          // did f4 get opened?
38          cout << "f4.is_open()=" << f4.is_open()<<endl;
39          cout << "f4.good()=" << f4.good()<<endl;
40          cout << "f4.bad()=" << f4.bad()<<endl;
41          cout << "f4.fail()=" << f4.fail()<<endl;
42         
43          // try to write using the f4 stream
44          f4 << buff << endl;
45     
46          // recheck f4's status
47          cout << "f4.is_open()=" << f4.is_open()<<endl;
48          cout << "f4.good()=" << f4.good()<<endl;
49          cout << "f4.bad()=" << f4.bad()<<endl;
50          cout << "f4.fail()=" << f4.fail()<<endl;
51          return 0;
52      }


******  Output  - MS Visual C++ 2008 ******

f2.rdstate()=2
f2.fail()=true
f2.bad()=false
Hey, I can't find "nofile", but who cares
Hey, I've decided to create a "file.one" file
//
f4.is_open()=false
f4.good()=false
f4.bad()=false
f4.fail()=true
f4.is_open()=false
f4.good()=false
f4.bad()=true
f4.fail()=true

******  Output  - gnu version 4.32b ******

f2.rdstate()=4
f2.fail()=true
f2.bad()=false
Hey, I can't find "nofile", but who cares
Hey, I've decided to create a "file.one" file
//
f4.is_open()=false
f4.good()=false
f4.bad()=false
f4.fail()=true
f4.is_open()=false
f4.good()=false
f4.bad()=false
f4.fail()=true

More I/O Members and Types
ios_base class
typedefs
typedef T3 openmode;       

constants
Open mode constants
These constants are used to assign a value to an openmode value. They represent the mode for opening a stream.

app        position to the end of the stream before each write operation.
ate        position to the end of the stream when the stream is opened.
binary        open the stream in binary mode (newlines are 1 byte).
in        open for input.
out        open for output
trunc        delete an existing file when opening.

Positioning constants
These constants are used to assign a value to a seekdir value. They used for relative positioning in a file stream with the seekg() and seekp() functions.

beg        position is relative to the beginning of a file stream.
cur        position is relative to the current position in a file stream.
end        position is relative to the end of a file stream.

More basic_istream members

istream& seekg(ios_base::pos_type pos);    positions to the location indicated by pos in a file stream.  pos_type is the type returned by the tellg() function.

istream& seekg(ios_base::pos_type pos, ios_base::seekdir dir);
    seeks to the position pos characters from dir in a file stream.

pos_type tellg();    returns the character position in the file stream. If the stream state is non-zero, then the function returns pos_type (-1).

More basic_ostream members

ostream& seekp(ios_base::pos_type pos);    positions to the location indicated by pos in a file stream.  pos_type is the type returned by the tellp() function.

ostream& seekp(ios_base::pos_type pos, ios_base::seekdir dir);
    seeks to the position pos characters from dir in a file stream.

pos_type tellp();    returns the character position in the file stream.  If the stream state is non-zero, then the function returns pos_type (-1).

Example 8-10 – File I/O – positioning in a file

1      // File ex8-10.cpp - file I/O
2     
3      #include <fstream>
4      #include <iostream>
5      #include <cstdlib>
6      #include <cstring>
7      using namespace std;
8     
9      int main()
10      {
11          int ch, i;
12     
13          // Open a file for output
14          ofstream fout("da_file");
15         
16          // Check file open
17          if (!fout) {
18              cerr << "I can't open \"da_file\"\n";
19              exit(EXIT_FAILURE);        // EXIT_FAILURE signifies failure
20          }
21     
22          // Write 4 lines into the file
23          fout << "Have a nice day\n";
24          fout << 7 << endl;
25          fout << 3.14159 << endl;
26          fout << hex << 123 << ' ' << oct << 123 << endl;
27         
28          // Close the file
29          fout.close();
30         
31          // Open the file for input
32          ifstream fin("da_file");
33         
34          // Check input file open
35          if (!fin) {
36              cerr << "I can't open \"da_file\"\n";
37              exit(EXIT_FAILURE);
38          }
39         
40          char buff[80];
41     
42          // Read each line from the file
43          while (!fin.getline(buff,80).eof()) {
44              // Print the length of the line and its contents
45              cout << strlen(buff) << '\t' << buff << endl;
46          }
47         
48          // Print the current position in the file
49          cout << fin.tellg() << endl;
50         
51          // Move to byte 7 (the 8th byte) in the file
52          fin.seekg(7,ios_base::beg);
53         
54          // Print the current position in the file
55          cout << fin.tellg() << endl;
56     
57          // Set the boooalpha flag for cout
58          cout.setf(ios_base::boolalpha);
59         
60          // Print the file's stream state and state bits
61          cout << "fin.rdstate()=" << fin.rdstate();
62          cout << " fin.bad()=" << fin.bad();
63          cout << " fin.fail()=" << fin.fail();
64          cout << " fin.eof()=" << fin.eof() <<endl;
65         
66          // Clear the stream state
67          fin.clear();
68         
69          // Print the file's stream state and state bits
70          cout << "fin.rdstate()=" << fin.rdstate();
71          cout << " fin.bad()=" << fin.bad();
72          cout << " fin.fail()=" << fin.fail();
73          cout << " fin.eof()=" << fin.eof() <<endl;
74         
75          // Move to byte 7 (the 8th byte) in the file
76          fin.seekg(7,ios_base::beg);
77         
78          // Print the current position in the file
79          cout << fin.tellg() << endl;
80         
81          // Read the next "word" from the file
82          fin >> buff;
83         
84          // Print the "word"
85          cout << buff << endl;
86         
87          // Print the current position in the file
88          cout << fin.tellg() << endl;
89         
90          // Read the next 10 characters
91          for (i = 0; i < 10; i++) {
92              ch = fin.get();
93              // Print counter, char (as int), char, and stream position
94              cout << i << '\t' << ch << '\t' << (char) ch << '\t'
95                  << fin.tellg() << endl;
96          }
97     
98          return 0;
99      }


******  Output (MS Visual C++ 2008)  ******

15      Have a nice day
1       7
7       3.14159
6       7b 173
-1
37
fin.rdstate()=0 fin.bad()=false fin.fail()=false fin.eof()=false
fin.rdstate()=0 fin.bad()=false fin.fail()=false fin.eof()=false
7
nice
11
0       32              12
1       100     d       13
2       97      a       14
3       121     y       15
4       10
        17
5       55      7       18
6       10
        20
7       51      3       21
8       46      .       22
9       49      1       23

******  Output (GNU 4.32b)  ******

15    Have a nice day
1    7
7    3.14159
6    7b 173
-1
-1
fin.rdstate()=6 fin.bad()=false fin.fail()=true fin.eof()=true
fin.rdstate()=0 fin.bad()=false fin.fail()=false fin.eof()=false
7
nice
11
0    32         12
1    100    d    13
2    97    a    14
3    121    y    15
4    10   
    16
5    55    7    17
6    10   
    18
7    51    3    19
8    46    .    20
9    49    1    21

What's the difference between the two outputs?  Why?

Example 8-11 - File I/O – positioning, modes, and stream state

1      // File ex8-ll.cpp – positioning, modes, and stream state
2     
3      #include <fstream>
4      #include <iostream>
5      #include <cstdlib>
6      using namespace std;
7     
8      void print_file(istream&);
9     
10      int main() {
11     
12          // Declare and open an output file stream
13          ofstream fout("da_file");
14         
15          // Check the file open
16          if (!fout) {
17              cerr << "I can't open \"da_file\"\n";
18              exit (EXIT_FAILURE);
19          }
20         
21          // write 3 lines into a new file
22          fout << "Have a nice day.\n";   
23          fout << "Have a great day.\n";
24          fout << "Have a totally excellent day.\n";
25         
26          // close the file                Why?
27          fout.close();                       
28         
29          // re-open the file as an fstream object for input and output
30          fstream finout("da_file",ios_base::in|ios_base::out);
31         
32          print_file(finout);
33         
34          // clear the EOF bit
35          finout.clear();
36         
37          // position to byte 7 in the file
38          finout.seekp(7,ios::beg);
39         
40          // Are the get and put pointers the same?
41          cout<< "finout.tellg()=" << finout.tellg()<< endl;
42          cout<< "finout.tellp()=" << finout.tellp()<< endl;
43         
44          // replace "nice" with "fine"
45          finout<< "fine";
46         
47          // Are the get and put pointers still the same?
48          cout<< "finout.tellg()="<< finout.tellg()<< endl;
49          cout << "finout.tellp()=" << finout.tellp () << endl;
50         
51          print_file(finout);
52         
53          // close the file
54          finout.close();
55         
56          // reopen the file in input/output/binary mode
57          finout.open("da_file",ios_base::in|ios_base::out|ios::binary);
58         
59          // write hey into the file
60          finout<< "hey";
61         
62          print_file(finout);
63         
64          // try again to write hey into the file
65          finout.seekp(0,ios::beg);
66          finout<< "hey";
67          print_file(finout);
68     
69          // try app mode
70          finout.clear();
71          finout.close();
72          finout.open("da_file",ios_base::in|ios_base::out|ios::app);
73          finout<< "hey";
74     
75          print_file(finout);
76     
77          return 0;
78      }
79     
80     
81      void print_file(istream& file)
82      {
83          cout<< "file.rdstate="<< file.rdstate() << endl;
84          char buffer[80];
85          file.seekg(0,ios::beg);
86          while (file.getline(buffer,sizeof(buffer))) {
87              cout<< buffer << endl;
88          }
89          cout << endl;
90      }


******  Output  (MS Visual C++ 2008)  ******

file.rdstate=0                        (32)
Have a nice day.
Have a great day.
Have a totally excellent day.

finout.tellg()=7                        (41)
finout.tellp()=7                        (42)
finout.tellg()=11                    (48)
finout.tellp()=11                    (49)
file.rdstate=0                        (51)
Have a fine day.
Have a great day.
Have a totally excellent day.

file.rdstate=7                        (62)
Have a fine day.
Have a great day.
Have a totally excellent day.

file.rdstate=7                        (67)

file.rdstate=0                        (75)
Have a fine day.
Have a great day.
Have a totally excellent day.
hey


******  Output  (GNU g++ 4.32)  ******

file.rdstate=0
Have a nice day.
Have a great day.
Have a totally excellent day.

finout.tellg()=7
finout.tellp()=7
finout.tellg()=11
finout.tellp()=11
file.rdstate=0                        (51)
Have a fine day.
Have a great day.
Have a totally excellent day.

file.rdstate=0                        (62)
heye a fine day.
Have a great day.
Have a totally excellent day.

file.rdstate=6                        (67)

file.rdstate=0                        (75)
heye a fine day.
Have a great day.
Have a totally excellent day.
hey

The following example illustrates binary file I/O. The example is a bit hokey, but it demonstrates input-output techniques that might be useful in a database application.

Example 8-12 – File I/O – read() and write()

1      // File: ex8-12.cpp - File I/O read() and write()
2     
3      #include <fstream>
4      #include <iostream>
5      #include <iomanip>
6      #include <cstdlib>
7      #include <cstring>
8      #include <string>
9      using namespace std;
10     
11      class Employee
12      {
13      public:
14          Employee() : age(0), salary(0.f) {}
15      private:
16          char empno[8];
17          char name[32];
18          unsigned short age;
19          float salary;
20          friend istream& operator>>(istream&, Employee&);
21          friend ostream& operator<<(ostream&, const Employee&);
22      };
23     
24      istream& operator>>(istream& in, Employee& E)
25      {
26          in >> E.empno >> E.name >> E.age >> E.salary;
27          return in;
28      }
29     
30      ostream& operator<<(ostream& out, const Employee& E)
31      {
32          out << setprecision(2) << fixed << showpoint << left;
33          out << setw(8) << E.empno
34              << setw(13) << E.name
35              << right << setw(3) << E.age
36              << setw(10) << E.salary;
37          return out;
38      }
39      class EmployeeFile
40      {
41      public:   
42          EmployeeFile(string filename = "empfile");
43          void print();                      // Why isn’t this const?
44          void open_for_read_write();
45          void close() { File.close(); }
46          bool operator!() const { return !File.rdstate(); }
47      private:
48          string Filename;
49          fstream File;
50          friend EmployeeFile& operator>>(EmployeeFile&, Employee&);
51          friend EmployeeFile& operator<<(EmployeeFile&, const Employee&);
52      };
53     
54      // constructor opens file in output/binary mode
55      EmployeeFile::EmployeeFile(string filename)
56      : Filename(filename), File(filename.c_str(),ios::out|ios::binary)
57      {
58      }
59     
60      void EmployeeFile::print()
61      {
62          Employee temp;
63     
64          // position to the beginning of the file
65          File.seekg(0,ios_base::beg);
66     
67          // read data from the file and print out each Employee record
68          while (!(*this>>temp)) {
69              cout << temp << endl;
70          }
71     
72          // clear the File stream state (after reading EOF)
73          File.clear();
74      }
75     
76      void EmployeeFile::open_for_read_write()
77      {
78          File.open(Filename.c_str(),ios::in | ios::out | ios::binary);   
79     
80          if (File.fail() ) {
81            cerr << "Unable to open Employee file: " << Filename << endl;
82            exit(-1);
83          }
84      }
85     
86      EmployeeFile& operator>>(EmployeeFile& EF, Employee& E)
87      {
88          EF.File.read((char*) &E, sizeof E);
89          return EF;
90      }
91      EmployeeFile& operator<<(EmployeeFile& EF, const Employee& E)
92      {
93          EF.File.write((char*) &E, sizeof E);
94          return EF;
95      }
96     
97      int main()
98      {
99          Employee temp;
100          EmployeeFile EmpFile("employee.dat");
101         
102          for (int i = 0; i<4; ++i) {
103              cout << "Enter empno name age salary\n";
104              cin >> temp;
105              EmpFile << temp;
106          }
107     
108          // close the file and reopen it in read-write mode
109          EmpFile.close();
110          EmpFile.open_for_read_write();
111     
112          EmpFile.print();
113          return 0;
114      }


******  Sample Run  ******

Enter empno name age salary
654321 Joe 35 80000
Enter empno name age salary
642731 Jim 55 85000
Enter empno name age salary
615787 Helen 60 90000
Enter empno name age salary
J00787 Susan 47 50000
654321  Joe           35  80000.00
642731  Jim           55  85000.00
615787  Helen         60  90000.00
J00787  Susan         47  50000.00

What is the purpose of the char* cast in the file.read() above?

Why is the EmployeeFile File stream opened by the constructor in write mode, then later closed and re-opened in read-write mode?

Example 8-13 - A DOS grep command

The following example is used to create a grep command for DOS. The UNIX grep command is used to search a file, or a list of files for the existence of a desired target string. This example was written for DOS, not UNIX. It demonstrates conditional compilation to allow for compiler differences.

After the program listing, sample compile commands are demonstrated and there is a note about executing the program under Windows XP.

1      // File: ex8-13.cpp - A grep command for DOS
2     
3      #include <fstream>
4      #include <iostream>
5      #include <cstdlib>
6      #include <cstring>
7      using namespace std;
8     
9      // The macro __GNUG__ is set for GNU C++
10      #ifdef __GNUG__
11      #include <unistd.h>        // for access()
12      #else
13      #include <io.h>         // for _access()
14      #endif
15     
16      int main(int argc, char* argv[])
17      {
18          char        filename[64],
19                      buffer[1024],
20                      command[128],
21                      tempFilename[9];
22          int            lineno,   
23                      hits = 0,
24                      files = 0,
25                      system_command_status;
26          ifstream    fin1,
27                      fin2;
28     
29          // Check command-line syntax
30          if (argc != 3) {
31              cerr << "Syntax error\ngrep [target text] [target file(s)]
32                   \n";
33              exit (-1);
34          }
35         
36          // create a temporary file to hold the filenames to be searched
37          strcpy(tempFilename,"tempa");        // first possible filename
38         
39          // The access() or _access() functions are used to status the
40           // existence of a file
41         
42          // If you're not using a GNU C++ compiler, use _access()
43      #ifdef __GNUG__
44          while (access(tempFilename,0) == 0 && tempFilename[4] <= 'z')
45          // If you're not using a GNU C++ compiler, use _access()
46      #else
47          while (_access(tempFilename,0) == 0 && tempFilename[4] <= 'z')
48      #endif
49              tempFilename[4]++;
50     
51          // If you've tried all filenames from "tempa" to "tempz",
52           // then give up
53          if (tempFilename[4] > 'z') {
54              cerr << "Unable to create a temp* file.  Please cleanup\n";
55              exit (-2);
56          }
57     
58          // Create the command:  "dir /b [filename(s)] > [tempfilename]
59          strcpy(command,"dir /b ");
60          strcat(command,argv[2]);
61          strcat(command," > ");
62          strcat(command,tempFilename);
63     
64          // system() allows you to issue operating system commands
65          system_command_status = system(command);
66     
67          // check the status of the system command
68          if (system_command_status == -1) {
69              cerr << "Error with system command: " << command << endl;
70              exit(-3);
71          }
72         
73          // open temporary file (containing names of files to be searched)
74          fin1.open(tempFilename);
75         
76          // Make sure the tempFilename is not empty
77          if (fin1.peek() == EOF) {
78              cerr << "Error: target file(s) do(es) not exist, dummy\n";
79              exit (-4);
80          }
81         
82          // for each file in tempFilename, search for the target string
83          while (fin1.getline(filename,sizeof(filename))) {
84     
85              // open the next file to be searched
86              fin2.open(filename);
87     
88              // increment file count
89              files++;
90     
91              // initialize line counter
92              lineno = 0;
93     
94              // clear errors in fin2 stream
95              fin2.clear();
96     
97              // position at the beginning of the file to be searched
98              fin2.seekg(0L, ios:: beg);
99     
100              // read each line from the file into buffer
101              while (fin2.getline(buffer,sizeof(buffer))) {
102     
103                  // increment line counter
104                  lineno++;
105     
106                  // does buffer contains the target string?
107                  if (strstr(buffer,argv[1])) {
108     
109                      // If so, increment hit counter
110                      hits++;
111     
112                      // display filename, line count, contents of line
113                      cout << filename << '[' << lineno << "] "
114                            << buffer << '\n';
115                  }
116              }
117     
118              // close the file to be searched
119              fin2.close();
120          }
121     
122          // close the temporary file
123          fin1.close();
124     
125          // Print summary information
126          cout << "Found " << hits << " occurrence(s) in " << files
127            << " file(s)\n";
128     
129          // create the DOS command to erase the tempFilename
130          strcpy(command,"erase ");
131          strcat(command,tempFilename);
132     
133          // Issue system erase command
134          system_command_status = system(command);
135     
136          // status system command
137          if (system_command_status == -1) {
138              cerr << "Error with system command: " << command << endl;
139              exit(-5);
140          }
141     
142          return 0;
143      }