This material is provided to the professors and students using Computer Science: A Structured Approach Using C, Second Edition. All reprints in any form must cite this copyright. Copyright(c) 2001 by Brooks/Cole A division of Thomson Learning Chapter 13 Binary Files Review Questions 1. b. False 2. a. True 3. a. True 4. b. False 5. b. False 6. a. All files must be opened before they can be used. 7. a. Because they are more flexible, binary files are more portable. 8. a. Error state 9. a. The file is placed in an error state regardless of the file mode. 10. b. "a+b" 11. a. fwrite 12. a. feof 13. d. fseek 14. c. key 15. b. Sequential files are often updated in an online environment. Exercises 16. a. "rb" is the reading mode for binary files, "r+b" is the reading and updating mode for binary files. b. "wb" is the writing mode for binary files, "w+b" is the writing and updating mode for binary files. c. "ab" is the appending mode for binary files, "a+b" is the appending and updating mode for binary files. 17. char *m = "wb" ==> char *m = "rb" 18. a. Error: fread needs four parameters. Either the size or the count parameter is missing. b. No error c. No error d. Error: fp must be the last parameter and a variable pointer is the first. e. Error: fp must be the last parameter and a variable pointer is the first. 19. a. No error b. Error: ftell needs only one parameter, file pointer. c. Error: fp must be the first parameter and the seek code is the last. d. No error e. No error 20. The position of the file marker is 5. See Figure 13.1. Figure 13.1 Solution for Chapter 13, Exercise 20. Page 13.1 21. C is printed. See Figure 13.2. Figure 13.2 Solution for Chapter 13, Exercise 21. 22. A is printed. See Figure 13.3. Figure 13.3 Solution for Chapter 13, Exercise 22. 23. D is printed. See Figure 13.4. Figure 13.4 Solution for Chapter 13, Exercise 23. 24. C is printed. See Figure 13.5. Figure 13.5 Solution for Chapter 13, Exercise 24. 25. Some garbage data because the file marker is located beyond the data. See Figure 13.6. Figure 13.6 Solution for Chapter 13, Exercise 25. 26. Assuming the sizeof int is two: The position of the file marker is: 10. See Figure 13.7. Figure 13.7 Solution for Chapter 13, Exercise 26. Page 13.2 27. 3 is printed. See Figure 13.8. Figure 13.8 Solution for Chapter 13, Exercise 27. 28. 4 is printed. See Figure 13.9. Figure 13.9 Solution for Chapter 13, Exercise 28. 29. In the call to fseek, it does not move in an increment of sizeof(int), so garbage is printed because the file marker is located at the middle of integer data (second byte of 4). See Figure 13.10. Figure 13.10 Solution for Chapter 13, Exercise 29. 30. 4 is printed. See Figure 13.11. Figure 13.11 Solution for Chapter 13, Exercise 30. Problems 31. /* ==================== cpyFile ===================== This function copies the contents of a binary file of integers to a second file. Pre fp1 is file pointer to open read file fp2 is file pointer to open write file Post file copied Return 1 is successful or zero if error */ int cpyFile (FILE *fp1, FILE *fp2) { /* Local Definitions */ int data; /* Statements */ fseek (fp1, 0, SEEK_END); if (!ftell (fp1)) { Page 13.3 printf ("\n\acpyFile Error : file empty\n\n"); return 0; } /* if open error */ if (fseek (fp1, 0, SEEK_SET)) return 0; if (fseek (fp2, 0, SEEK_SET)) return 0; } while (fread (&data, sizeof (int), 1, fp1)) fwrite (&data, sizeof (int), 1, fp2); return 1; /* cpyFile */ 32. /* ============== printRec ================= This function prints a specified number of records from the beginning of a file. Pre pointer to a binary file open for reading an integer representing number of records Post data printed If error occur, such as fewer records in the file than requested, it returns a zero */ int printRec (FILE *binfile, int num) { const char *errNumRecs = "\n\aFile contains fewer than %d records.\n\n"; /* Local Definitions */ STR data; int retval; int i; /* Statements */ printf ("\nPrinting %d records:\n", num); } fseek (binfile, 0, SEEK_SET); for (retval = 1, i = 0; i < num && retval; i++) { retval = fread (&data, sizeof (STR), 1, binfile); if (retval) printf ("\nRecord #%d: %5d %8.3f", (i + 1), data.i, data.f); else printf (errNumRecs, num); } /* for */ return retval; /* printRec */ 33. /* ============ fileCmp ============= This function compares two files Pre two pointers to opened binary files Post result of comparison returned if equal, return 0--if not equal, return 1 */ int fileCmp (FILE *binfile1, Page 13.4 FILE *binfile2) { /* Local Definitions */ char data1; char data2; int check = 0; int retval = 0; /* Statements */ fseek (binfile1, 0, SEEK_END); fseek (binfile2, 0, SEEK_END); if (ftell retval else { fseek fseek (binfile1) = 1; != ftell (binfile2)) (binfile1, 0, SEEK_SET); (binfile2, 0, SEEK_SET); while (fread (&data1, sizeof (char), 1, binfile1 && fread (&data2, sizeof (char), 1, binfile2 && !check) check = data1 – data2; } if (check) retval = 1; } /* else files are equal length */ return retval; /* fileCmp */ 34. /* ================== cntItem ================= Return number of items in a binary file. Pre pointer to opened binary file of STR structs Post the number of items in a binary file */ long int cntItem (FILE *binfile) { /* Statements */ fseek (binfile, 0, SEEK_END); return ( ftell (binfile) / sizeof (STR) ); } /* cntItem */ 35. /* ================== printLast ============== This function prints the last integer in a binary file of integers. Pre pointer to binary file opened for reading Post last integer printed */ void printLast (FILE *binfile) { /* Local Definitions */ int data; /* Statements */ fseek (binfile, 0, SEEK_END); if (ftell (binfile) == 0L) printf ("\n\aThe file is empty\n\n"); Page 13.5 else { } fseek (binfile, -1 * sizeof(int), SEEK_CUR); fread (&data, sizeof(int), 1, binfile); printf ("\nThe last integer is %d\n", data); } /* else file !empty */ return; /* printLast */ 36. /* Global Declarations */ typedef struct { int data; char c; } STR; /* ===================== delItems ===================== This function removes all items with specified value (data) from a binary file. Pre binfile is the name of the binary file Post matching items deleted */ int delItems (char *binfile) { /* Local Definitions */ FILE *fpbin; FILE *fptmp; STR rec; int value; /* Statements */ if (!(fpbin = fopen (binfile, "rb"))) { printf ("\nCan’t open %s for read\n", binfile); exit (100); } /* if open error */ if (! (fptmp = tmpfile())) { printf ("\nCan’t open temporary file\n"); return (200); } /* if open error */ printf ("\nEnter the value of data: "); scanf ("%d", &value); while (fread (&rec, sizeof (STR), 1, fpbin)) { if (rec.data != value) fwrite (&rec, sizeof (STR), 1, fptmp); } /* while */ fclose (fpbin); rewind (fptmp); if (!(fpbin = fopen (binfile, "wb"))) { printf ("\nCan’t open %s for write\n", binfile); Page 13.6 exit (101); } /* if open error */ while (fread (&rec, sizeof (STR), 1, fptmp)) fwrite (&rec, sizeof (STR), 1, fpbin); } fclose (fpbin); fclose (fptmp); return; /* delItems */ 37. /* ================ apendFile ================ This function appends one binary file to another. Pre binfile1 is binary write file binfile2 is binary read file Post binfile2 appended to binfile1 */ void apendFile (FILE *binfile1, FILE *binfile2) { /* Local Definitions */ STR rec; /* Statements */ fseek (binfile1, 0, SEEK_END); fseek (binfile2, 0, SEEK_SET); } while (fread (&rec, sizeof (STR), 1, binfile2)) fwrite (&rec, sizeof (STR), 1, binfile1); return; /* apendFile */ 38. /* ================ cpyOddEven ================== This function copies odd items to a second binary file and even items to a third binary file. Pre a pointer to a binary file open for reading Post New files created – returns 0 for success */ int cpyOddEven (FILE *bin1) { /* Local Definitions */ STR rec; FILE *bin2; FILE *bin3; int cnt = 0; /* Statements if (!(bin2 printf if (!(bin3 printf */ = fopen ("evens.bin", "wb"))) ("\nCan’t open evens.bin\n"), exit (100); = fopen ("odds.bin", "wb"))) ("\nCan’t open odds.bin\n"), exit (200); fseek (bin1, 0, SEEK_SET); while (fread (&rec, sizeof (STR), 1, bin1)) { cnt++; if (cnt % 2 == 0) Page 13.7 fwrite (&rec, sizeof (STR), 1, bin2); else fwrite (&rec, sizeof (STR), 1, bin3); } /* while */ } fclose (bin2); fclose (bin3); return 0; /* cpyOddEven */ 39. /* ================= allocAry =================== This function reads items from a binary file and copies them to a dynamically allocated array. Pre a pointer to a binary file open for reading Post array loaded and returned – NULL if error */ STR *allocAry (FILE *binfile) { /* Local Definitions */ long int count; int i = 0; STR rec; STR *ary; /* Statements */ fseek (binfile, 0, SEEK_END); count = ( ftell (binfile) / sizeof (STR) ); rewind (binfile); ary = (STR*) calloc ((int)count, sizeof (STR)); } if (ary) { while (fread (&rec, sizeof (STR), 1, binfile)) { ary[i] = rec; i++; } /* while */ } /* if */ return ary; /* allocAry */ 40. /* ================ apendLong =========== This function takes a binary file of long integers and appends a long integer at the end that is the sum of all integers in the original file. Pre pointer to binary read/write file Post total appended to file */ void apendLong (FILE *binfile) { /* Local Definitions */ long int data; long int total = 0; /* Statements */ fseek (binfile, 0, SEEK_SET); Page 13.8 while (fread (&data, sizeof(long int), 1, binfile)) total += data; } fseek (binfile, 0, SEEK_END); /* or SEEK_CUR */ fwrite (&total, sizeof(long int), 1, binfile); return; /* apendLong */ Page 13.9