Topical Information

This lab gives you practice reading from a file where you don't know ahead of time how many data items are in the file. It can also give you practice using streams with classes. (You might also get some practice with (C)strings here.)

Program Information

Write a program that transfers the contents of one file to a second file. The first file will contain an arbitrary (unknown) number of data groups. A data group will consist of a person's name (a (C)string containing spaces), the person's student ID (a large integer), the person's GPA (a floating point number), and the person's letter grade (a single character). You can design the order of the data within each group and the actual values to use. (It would be educational for you to experiment with different orders for the data values.) Remember that your program cannot know how many data groups are in the file ahead of time!

You'll have to read the files' names from the user. Protect your program against any errors that may occur during the opening of the files.

Try to use functions to break up the program into more manageable pieces.


As an example, you might have the data file contain:

Jason James
123456
9.2
B
Tammy James
123457 11.2 A
Familiar Kensei James
123458
5.6 D
Quincy 2005 is Awesome
110121 8.4
B

Note how the data is always in the same order (the one you decide upon — this is just a possible order of the prescribed data pieces), but the spacing between data items is potentially varied.

Your program's interaction might look something like (the parts in this color are typed by the user):

$ ./copypeople.out

                 Welcome to the People Data Copying Program!!!

Please enter the name of your data file:  bob.dat

I'm sorry, I could not open 'bob.dat'.  Please enter another name:
students

File 'students' opened successfully!

Please enter the name of the copy file:  /can't write here

I'm sorry, I could not open '/can't write here'.  Please enter another name:
students.bak

File 'students.bak' opened successfully!

Copying data from 'students' to 'students.bak'...

Done copying data!

Thank you for using the PCP!!

Endeavor to have a tremendous day!

$ cat students.bak
Jason James
123456
9.2
B
Tammy James
123457
11.2
A
Familiar Kensei James
123458
5.6
D
Quincy 2005 is Awesome
110121
8.4
B
$

Again, the second file will be an exact data copy of the first. (By this I mean you are not to perform a character-by-character copy of the file, but a copy of the DATA from the file. Note how I described to you the TYPES of data in the file and not just their meanings. I did not do this on accident — I did it so you would know what they were and could use them to design your input sequence!)

And note that the copied file doesn't have exact same spacing as the original file. The data order is the same and that's about it.

In fact, your main should contain something like:

    in.peek();
    while (!in.eof())
    {
        student.read(in);
        student.write(out);
        in.peek();
    }

(If you were using objects, otherwise it might look more like:

    in.peek();
    while (!in.eof())
    {
        read_student(in, name, id, gpa, grade);
        write_student(out, name, id, gpa, grade);
        in.peek();
    }

Although I'd think you'd like to practice using classes as much as possible.)

Thought Provoking Questions

  1. What weird behavior does open exhibit for output files by default? How do we fix this problem?

  2. How much does spacing matter in the input file? The output file? (Hint: Would it matter if it weren't present at all? If there were many, many spaces?)

  3. Problems with the (C)string piece of data:

    1. What problem might you have with the (C)string data (being as it is 'mixed' with so many other data types in this file: numbers and characters and such)? (Hint: Is the (C)string data one or multiple words?) Is this difficult to fix? What assumption did you make to solve this problem?

    2. If the (C)string had to be placed after the other data — at the end of the data group/block, what problem might arise? How do we typically avoid this situation (again, assuming the data has to be in that order)? [Assume you have re-written your code to deal with the new data order — but do not do so.]

    3. Think about, but do not fix, the potential problem of the user's (C)string being longer than you had anticipated. (Answer this question even if you used the string class to code your program!)

    1. What function is used to tell when you've reached the end of a stream?

    2. Can this function be used on the keyboard stream?

  4. How do you pass a stream to a function?

  5. Why is it a good idea to make input functions ignorant of whether or not a stream is cin or a file? Output functions/cout/file?

  6. Why do we close files?

This assignment is (Level 1).

Options