Exercise 14 File I/O
Eric Chen (last modified 2019.04.28)
Intended Learning Outcomes
When you have done this exercise, you will
1) Understand the difference between text file and binary files 2) Be able to do simple file input/output
3) Be able to understand buffer overflow bug
4) Be able to use C random number generator
Note: if you have not downloaded the C source files (in the zipped file), you should do it first.
Task 1 text file vs binary file
From this exercise, you are going to learn how to output in text or binary format. You will know the difference between a text file and a binary file.
It is not required to know how to read and write binary data. From this example, you can still observe the difference between a text file and a binary file.
Given the following program (textvsbinaryfile.c find it in the zipped file on course page):
void textWrite2Integers( FILE *txtfp, int a, int b ); void binaryWrite2Integers( FILE *binfp, int a, int b ); int main ( ){
int a, b;
FILE * txtfp; // for text output
FILE * binfp; // for binary output
char * txtfile = “my.txt”; // text file name char * binfile = “mybin”; // binary file name
/* open files for writing*/ txtfp = fopen (txtfile, “w”); binfp = fopen (binfile, “wb”);
/* read in two integers*/
printf(“Enter 2 integers: “); scanf(“%d %d”, &a, &b);
a *= 2; b *= 3;
/* output 2 integers to a text file*/ textWrite2Integers( txtfp, a, b );
/* output 2 integers to a binary file*/ binaryWrite2Integers( binfp, a, b);
/* close files*/
fclose( txtfp ); fclose( binfp );
return 0; }
/* output 2 integers to a text file*/
void textWrite2Integers( FILE *txtfp, int a, int b ){
fprintf(txtfp, “%d %d”, a, b); }
1
/* output 2 integer to a binary file*/
void binaryWrite2Integers( FILE* binfp, int a, int b ){
fwrite (&a, sizeof(int), 1, binfp);
fwrite (&b, sizeof(int), 1, binfp); }
1) Compile the program. Run the program and enter 2 small integers. Write down these integers on a paper.
2) Check the output files my.txt and mybin. What are their sizes in bytes? If you use MS Windows, you check the file size by locating the file in Windows Explorer, and right-clicking on the file, choosing the properties. In the opened window, you can find the exact size in bytes of the file.
3) Can you read my.txt and mybin (open it in a text editor or console environment)? Why or why not?
4) Run the program again, enter 2 large integers at this time. Write down these integers on a paper.
5) Check the output files my.txt and mybin. What are their sizes now?
6) What you can learn from this program about the size? Why the size for the binary files are not
changed?
7) Add C code to the program, so that it reads 2 integers back from my.txt and mybin (optional, for
binary file input). Print these values on the screen.
Task 2 Random function and array
This exercise is to learn how to use C random function and array.
Write a program that generates a specified number of random numbers from 0 to 20 (excluding 20), writes the numbers into a text file. Then it reads back from the file, one by one, and calculates the number distribution ( showing the frequency a number appears within 0..20), and prints the distribution. A good random number generator should provide the uniform distribution. The sample output from my implementation is as follows. The program skeleton is given on the next page.
If you want to develop this program further, you can do the analysis on the distribution by computing the minimum, maximum, and average frequency.
2
Follow the layout in file random-number-distribution.c (find it in the zipped example code file on course page), fill in the missing C code.
/* random number between 0..MAX-1 */
#define MAX 20
/* prototypes for the functions */
void generateRandomNumbers(int n, int range, FILE *fp); void distribution( int range, FILE *fp);
main ( ){
char fname [100]; // to keep the file name
int n, // number of random numbers to generate
range; // the range of the numbers [0..range-1) FILE *fp;
range = MAX; //the random numbers in [0..MAX-1) /* get value for n */
printf(“Enter the # of numbers to generate: “);
/* use scanf ( ) to read in the value to n */
scanf( ….); // complete the statement
/* read in the file name to fname*/ printf(“Enter the file name: “);
scanf ( … ); // complete the statement
/* open file for writing*/ ….
/* call the function to generate the numbers and save them to the file*/ generateRandomNumbers( … ); // complete this statement
/* close the file */
fclose ( … ) ; // complete the statement
/* now to do the analysis on the numbers*/ /* first open the file for reading */
…
/* call the distribution to do the calculation of the distribution of the n$ distribution ( …); complete the statement
/* close the file*/
fclose( … ); // complete the statement
getchar(); getchar( ); //wait for Entry key to exit }
/* generate n random numbers in the range, and save them to the file*/ void generateRandomNumbers( int n, int range, FILE *fp){
// implement the function }
/* read numbers from the file, calculate the distribution, and print the result$ void distribution (int range, FILE *fp){
// implement the function }
3
Task 3 Buffer Overflow
This task introduces a famous software bug¡ªbuffer overflow.
Buffer overflow is a common bug in software. It is often explored and becomes a security problem. Study the following program to have a feeling on buffer overflow bug. The program(buffer- overflow.c) is included in the source files for the unit.
char str[20]; int a ;
a = 100;
printf(“Enter a string : “); gets(str);
printf(“str = %s, a = %d\n”, str, a);
a = 100;
printf(“Enter a string : “); fgets(str, 20, stdin);
printf(“str = %s, a = %d\n”, str, a);
1) Compile the run the program. Are output correct?
2) Run the program again. Now enter a long string with more than 20 characters. Are output
correct (the string you entered printed? The value of a is 100?)?
3) Study the difference between gets( ) and fgets( ). In practice, you should not use gets( ) to
avoid the buffer overflow.
A similar problem exists for scanf( ). When you use scanf( ) to read in a string, if you do not specify the maximum number of chars are to read, your program have the buffer overflow bug. Modify the above program to use scanf( ), and repeat 1)¡ª3):
scanf(“%s”, str); // instead of gets() scanf(“%19s”, str); // instead of fgets( )
Remember that the string you enter using scanf(“%s”, str) or scanf(“%19s”, str) should not contain blank spaces. Otherwise, it only reads chars until it reaches the blank space or a newline.
4
Task 4 A Simple Substitution Cipher
This exercise is to do practice on text file i/o.
In traditional cryptography, a simple substitution cipher is a cipher that has been in use for many hundreds of years. The famous Caesar Cipher is a simple substitution cipher. With this scheme, we shift the alphabets by some number. The general substitution cipher is development from Caesar Cipher. It substitutes every plaintext character for a different cipher text character. So the encryption/decryption key is to have the substitution scheme. Read more about the substitution cipher at https://www.programmingalgorithms.com/algorithm/simple-substitution-cipher?lang=C
Develop a C program to implement the simple substitution cipher: given a text file name, read the characters in the file, and substitute the characters with a simple substitution schema.
5