This lab should be completed in lab. If you do not complete the four parts below in lab, submit them to the web submission page by 6 PM Saturday.
- To give you some experience working with the binary representation of information inside of computers
- converting between decimal, binary, octal, hex and ascii
- reading and writing binary data from files
- To give you some experience using C++ exceptions to handle error conditions in your programs
Reading and Writing Binary data:
Here is a sample program and data file (sample_binary1.zip) which may help you with this exercise.
Here are Fernando Paniagua's powerpoint slides on binary numbers and reading and writing binary data.
- You can read and write data in binary format by opening the file in binary mode
and using the ifstream's read(...) and ofstream's write(...) functions. This is easy
to do for data in char arrays, and only slightly more complicated for other data types
such as int, float and double.
- To open a file in binary format, you simply provide a second parameter along with the filename: ios::binary
ifstream ifs("junk.dat", ios::binary);
- read(...) and write(...) both take 2 parameters. The first is the address of a
char array in memory where the data should be read from (written to); the second is the
number of bytes to read (write). Recall that the name of an array is its address in C++.
For data types other than char, we have to reinterpret_cast the array to make it
look like a char array. To do this (assuming an array "int myints[10]"),
ofs.write(reinterpret_cast<char *>(myints), 10*sizeof(int));
reinterpret_cast<char *> tells the compiler to treat the address myints as if it were
the address of a char array.10*sizeof(int) is the number of bytes to write. In this case, it's ten times the size of an int (usually 4 bytes).
Exceptions:
Click here to read background on C++ Exceptions
In this section, you will work with the same bit patterns, but treat them as character data or as integer data. In the first few parts (1-4) you'll determine the binary representation by hand, then read and write the data to a file to get you familiar with how data is read and written in binary format. In the last part, you will write and read a large amount of numeric data to a file, first in ascii format (as we did with our pixel data in our PGM images), the redo the program to use binary data. You should discover that reading and writing binary data is much faster. Why is this?Do the following conversions by hand, and then verify with the calculator on the Mac:
1. convert the following from integer to binary, octal and hex:116 104 101 32
2. convert the following from hex to decimal and to ASCII (see http://www.lookuptables.com/ for an ascii table if you need one.)
0x6a 0x75 0x6d 0x70
3. convert the following from hex to decimal. (Note: it is the same bit pattern as #2)
0x6a756d70
2. Write a program which does the following:
a. Declares two integer arrays, a & b, containing the numbers:
- array a: 1952998688 1903520099 1797284466 1870097952 1718581280 1786080624
- array b: 0 0 0 0 0 0
b. Opens a file called "binary.dat" and writes the array a to the file in binary format
c. closes the file (be sure to do this, or the rest of the program won't work right!)
d. Opens the file "binary.dat" for reading, and reads the data into the array b
e. outputs both arrays a & b to the console so you can verify that you read the data back again properly.3. Switch places, so the 2nd person does some programming. Write a program which reads the file "binary.dat" from part 2 into a char array (it will have to be 24 chars long), and outputs the chars to the console
4. Open the file 'binary.dat' with Textedit, and verify that it contains the data your program 3 printed out.
Explain to the TA how the same binary data can represent numbers in problem 2, yet contain text in problem 3.
5. Here is a program which does the following:
a. declares an unsigned char array 4*1048576 chars long (like 8-bit pixels, for example).
b. initializes them to random values between 0 & 255 (inclusive)
c. writes the values to a data file as (not-binary) integer values (like we have done with our PGM images)
Run this program and time how long it takes to run. (If it takes less than a few seconds, double or quadruple the size of the array.)
Then, replace the output and input with writing and reading the data in binary format. Run your program and time how long it takes to run.
Discuss between you and your partner why you think it takes less time to write the data in binary than as integer values, and why the file size is smaller. Explain your answer(s) to the TA when he checks you off for this assignment.
1. Basic C++ Exceptions
Here is a sample program which throws string exceptions. It catches most of them, but also gives you the chance to see what happens if an exception occurs and your program doesn't catch it.
a. Study the program so you understand what it does, then compile and run it. note: string("...") constructs a string for us to throw; if we just used throw "..." , then we would throw a c-string (null-terminated char array), not a C++ string object.
b. Answer yes so it throws an exception but does not catch it. This will show you what happens if an exception is thrown but not caught.
c. Run it several more times and throw exceptions in main, mysub1 and mysub2 so you see how exceptions can be caught and handled.
d. Modify it so it catches the exception from my_sub2 inside of my_sub1, outputs the exception message from my_sub2, and then returns normally from my_sub1 even if it caught an exception in my_sub2. This will show you that you can catch exceptions, do something about them, and let your program continue with normal execution.
Now switch places and let the other partner do some programming.
2. Complete this program so readPGM throws an integer exception if it encounters a problem, and the main routine catches and handles it appropriately. readPGM throws an integer error with the following values:
0 -- file doesn't exist
1 -- file isn't a P2 PGM (1st 2 chars aren't "P2")
2 -- header isn't valid: ncols, nrows or maxval is zero or less
3 -- image contains bad pixels -- pixels > maxval or pixels < 0If the program reads a good image, it should display the header and the first few pixels. If the program cannot read an image (error 0,1 or 2) it should print an appropriate error message and abort. If it reads an image with bad pixels values, it should display a warning message, then continue on to display the first few pixels.