29. Is There Another Way to Save Files?

Use Random Files

image

This chapter shows you how to skip around in a file, reading and writing data as you go. The preceding chapter introduced methods you can use to write, read, or append data to a file. The problem is that once you open a sequential file for reading, you can only read it.

There might be times when you want to read a customer structure from disk and change the customer’s balance. You certainly wouldn’t want to have to create a new file just so you could write that one change. Instead, you would want to read the customer information into a variable, change it, and then write it back to disk exactly where it first resided. As Figure 29.1 shows, random files let you skip around in the file, reading and writing at any point you access.

Figure 29.1. Random files let you read and write data in any order.

image

The physical layout of a file doesn’t define the type of file (whether random or sequential). You can create a file sequentially and then read and change it randomly. To C, a file is just a stream of bytes, and the way you access it isn’t linked to any format of the file.

Opening Random Files

To read or write a file randomly, you must open the file randomly. Table 29.1 lists the modes that access random files. As you can see, the cornerstone of random-access files is the use of the plus sign combined with the access modes you learned about in the previous chapter.

Table 29.1. The random-access fopen() modes.

image

Note

image

As with sequential files, the access mode is a string that appears as the last argument of fopen(). You will close open random files with fclose(), just as you do with sequential files.

All three modes let you read and write to the file. The access mode you choose depends on what you want to do first to the file. If the file exists and you want to access the file randomly, use the r+ mode. If you want to create the file, use w+. (If the file already exists, C overwrites the existing version.) If you want to add to the end of a file, but optionally “back up” and read and write existing data, use a+.

Here is a sample fopen() statement that opens an existing file for writing and reading:

fptr = fopen("C:\LETTERS.DAT", "w+");  /* Opens for
                                           write, then read */

As with sequential files, the fptr variable must be a file pointer variable. The double backslash is needed if you specify a pathname. Remember that fopen() returns a zero if the open fails.

Note

image

You can specify a long pathname if you want to. For instance, the filename might look something like this:

"C:\ANDY\WORK\CORRESP\LETTERS.DAT"

Also, you can store the filename in a character array and use the character array name in place of an actual string literal for the filename. You can use either uppercase or lowercase letters for the filename.

Moving Around in a File

Use the fseek() function to move around in a file. After you open a file, C initializes the file pointer to point to the next place in the file you can read or write. fseek() moves the file pointer so that you can read and write at places that would normally not be pointed at using sequential access. Here is the format of fseek():

fseek(filePtr, longVal, origin);

The filePtr is the file pointer used in the fopen() function that used a random-access mode. The longVal is a long int variable or literal that can be either positive or negative. The longVal is the number of bytes to skip forward or backward in the file. The origin is always one of the values shown in Table 29.2. origin tells fseek() from where to start seeking.

Table 29.2. origin values that can appear in fseek().

image

The origin value tells C the position from where you want to access the random file next. Once you position the file pointer with fseek(), you can use file input and output functions to write and read to and from the file. If you position the file pointer at the end of the file (using SEEK_END), and then write data, new data will go to the end of the file. If you position the file pointer over existing data (using SEEK_SET and SEEK_CUR), and then write new data, the new data will replace the existing data.

Warning

image

Use fseek() for random-access files only. Sequential files can be accessed only in the order of the data.

Clue

image

Table 29.2’s values are in uppercase, which implies that they’re defined somewhere. They’re defined in STDIO.H using #define directives.

The following program opens a file for random-access mode, writes the letters A through Z to the file, and then rereads those letters backwards. The file doesn’t have to be reopened before the reading begins because of the random-access mode "w+".

image

Clue

image

As you can see, fputc() is a great function for outputting individual characters to a file. fgetc() reads individual characters from a file. fputc() and fgetc() are to putc() and getc() what fputs() and fgets() are to puts() and gets().

Assuming that the file of letters still resides on the disk from the last program, this next program asks the user which position he or she wants to change. The program then positions the file pointer with fseek() and writes an * at that point before fseek()ing to the beginning of the file and printing it again.

image

The program prints the contents of the file after the * is written at the position indicated by the user. Here is a sample session:

image

As you can see, the fourth position of the alphabetical file, the letter D, now contains an asterisk. The rest of the file remains unchanged.

Rewards

image

• Use a plus sign in the fopen() mode string if you need to change data in a file.

• Remember that fseek() moves a file pointer all around a random file so that you can read or write from the beginning, middle, or end.

Pitfalls

image

• Don’t forget to close a file when you are done with it.

• Don’t attempt to work with a file if the fopen() fails (by returning a zero).

In Review

The goal of this chapter was to explain how random-access files work. Once you open a file in random-access mode, you can read and write to that file in any order you need to. The fseek() function is the built-in function that skips around the file from position to position.

Being able to change the contents of a file is important when you want to update file data. Often you will want to change a person’s address, change an inventory item’s quantity, and so on without rewriting the entire file as you would have to if you used sequential file processing.

Code Example

image

Code Analysis

This code contains a complete program that writes structure data to a random-access file. The program could have just as easily written to a sequential file, but the fprintf() ensures that each structure written to the disk has the same format and length—a three-character string followed by a floating-point value.

You can easily write the code to read or change any record in the file using this fseek():

fseek(gradePtr, recNo * sizeof(struct std), SEEK_SET);

in which recNo is a record number that the user wants to change.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.222.12