You are on page 1of 37

C File Processing: C File Processing:

Chapter 11: Chapter 11: Deitel and Deitel Deitel and Deitel Norris Edwards Norris Edwards Porterville College Porterville College
Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 1

Unit Objectives: Unit Objectives:


By the end of this unit you will be able By the end of this unit you will be able to :: to Create, read, write and update files. Create, read, write and update files. Create, and process sequential Create, and process sequential access files. access files. Create and process Random access Create and process Random access files. files.

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 2

Introduction: Introduction:
Storage of data in variables and arrays is Storage of data in variables and arrays is always temporary always temporary All such data is lost when the program All such data is lost when the program terminates terminates In order to have more permanent storage of In order to have more permanent storage of data we must utilize data files. data we must utilize data files. Data files can be created, updated, and Data files can be created, updated, and processed by C programs processed by C programs Files are used for permanent storage of large Files are used for permanent storage of large amounts of data amounts of data Storage of data in variables and arrays is Storage of data in variables and arrays is only temporary only temporary
Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 3

The Data Hierarchy: The Data Hierarchy:


Bit Bit

Byte Byte

Field Field Record Record File File Database Database


Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 4

The Data Hierarchy: The Data Hierarchy:


Sally Sally Judy Judy Iris Iris Randy Randy Judy Judy Judy Judy Blue Blue

File File

Black Black Orange Orange Red Red

Record Record Field Field

01001010 Byte 01001010 Byte Bit Bit

1 1

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 5

Files and Streams: Files and Streams:


C views each file as a sequence of bytes C views each file as a sequence of bytes File ends with the end-of-file marker File ends with the end-of-file marker Or, file ends at a specified byte Or, file ends at a specified byte A stream is created when a file is opened A stream is created when a file is opened Provide communication channel between files and Provide communication channel between files and programs programs Opening a file returns a pointer to a FILE structure Opening a file returns a pointer to a FILE structure Example file pointers: Example file pointers: stdin --standard input (keyboard) stdin standard input (keyboard) stdout --standard output (screen) stdout standard output (screen) End of stderr --standard error (screen) stderr standard error (screen)

0 0

1 1

2 2

3 3

4 4

5 5

8 8

7 7

8 N-1 File 8 N-1 Marker

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 6

Files and Streams: Files and Streams:


FILE structure FILE structure File descriptor --Index into operating system array called the File descriptor Index into operating system array called the open file table open file table File Control Block (FCB) --Found in every array element, File Control Block (FCB) Found in every array element, system uses it to administer the file system uses it to administer the file Read/Write functions in standard library Read/Write functions in standard library fgetc --reads one character from a file fgetc reads one character from a file Takes a FILE pointer as an argument Takes a FILE pointer as an argument fgetc( stdin ))equivalent to getchar() fgetc( stdin equivalent to getchar() fputc --writes one character to a file fputc writes one character to a file Takes a FILE pointer and a character to write as an Takes a FILE pointer and a character to write as an argument argument fputc( 'a', stdout ))equivalent to putchar( 'a' )) fputc( 'a', stdout equivalent to putchar( 'a' fgets --read a line from a file fgets read a line from a file fputs --write a line to a file fputs write a line to a file fscanf //fprintf --file processing equivalents of scanf and fscanf fprintf file processing equivalents of scanf and printf Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 7 printf

Creating a Sequential Access File: Creating a Sequential Access File:


C imposes no file structure C imposes no file structure No notion of records in a file No notion of records in a file Programmer must provide file structure Programmer must provide file structure Creating a File Creating a File FILE *myPtr; --creates a FILE pointer FILE *myPtr; creates a FILE pointer myPtr = fopen("myFile.dat", openmode); myPtr = fopen("myFile.dat", openmode); Function fopen returns a FILE pointer to file specified Function fopen returns a FILE pointer to file specified Takes two arguments --file to open and file open mode Takes two arguments file to open and file open mode If file not opened, NULL returned If file not opened, NULL returned fprintf --like printf,,except first argument is a FILE fprintf like printf except first argument is a FILE pointer (the file receiving data) pointer (the file receiving data) feof(FILE pointer) --returns true if end-of-file indicator feof(FILE pointer) returns true if end-of-file indicator (no more data to process) is set for the specified file (no more data to process) is set for the specified file
Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 8

Creating a Sequential Access File: Creating a Sequential Access File:


fclose(FILE pointer) --closes specified file fclose(FILE pointer) closes specified file Performed automatically when program ends Performed automatically when program ends Good practice to close files explicitly Good practice to close files explicitly Details Details Programs may process no files, one file, or many files Programs may process no files, one file, or many files Each file must have an unique name and will have a different Each file must have an unique name and will have a different pointer pointer All file processing must refer to the file using the pointer All file processing must refer to the file using the pointer Mode Description Mode Description rr w w aa r+ r+ w+ w+ a+ a+ Open aafile for reading Open file for reading Create aafile for writing. If the file already exists, current data is lost Create file for writing. If the file already exists, current data is lost Append; open or create aafile for writing at end of file. Append; open or create file for writing at end of file. Open aafile for update (read and writing) Open file for update (read and writing) Create aafile for update, if file already exists, current data is lost Create file for update, if file already exists, current data is lost Append; open or create aafile for update, writing to end of file. Append; open or create file for update, writing to end of file.
Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 9

Creating Sequential Files: Creating Sequential Files:

/* Fig. 11.3: fig11_03.c Create a sequential file */ #include <stdio.h>

fopen, Open a file. fopen, Open a file. FILE *fopen( const char *filename, const FILE *fopen( const char *filename, const

int main() char *mode ); char *mode ); { Function Required Header Compatibility Function Required Header Compatibility int account; fopen<stdio.h> fopen<stdio.h> char name[ 30 ]; ANSI, Win 95, Win NT ANSI, Win 95, Win NT double balance; FILE *cfPtr; /* cfPtr = clients.dat file pointer */ if ( ( cfPtr = fopen( "clients.dat", "w" ) ) == NULL ) printf( "File could not be opened\n" ); else { printf( "Enter the account, name, and balance.\n" ); printf( "Enter EOF to end input.\n" ); printf( "? " ); scanf( "%d%s%lf", &account, name, &balance );

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 10

Creating Sequential Files: Creating Sequential Files:

while ( !feof( stdin ) ) { fprintf( cfPtr, "%d %s %.2f\n", account, name, balance ); printf( "? " ); scanf( "%d%s%lf", &account, name, &balance ); feof feof Tests for end-of-file on a stream. } Tests for end-of-file on a stream.

int feof( FILE *stream ); fprintf, int feof( FILE *stream ); fprintf, Function Required Header Compatibility Print formatted data to a stream. Function Required Header Compatibility Print formatted data to a stream. fclose( cfPtr ); feof<stdio.h> FILE *stream, const char int fprintf( feof<stdio.h> FILE *stream, const char int fprintf( } ANSI, Win [, argument ]...); *format [, argument ANSI, Win 95, Win NT ]...); *format 95, Win NT fclose, , fclose Closes aastream ((fclose) fclose) Closes Return Value stream Header Compatibility return 0; Function Required Header Compatibility Return Value ( FILE *stream ); Function Required int fclose ( FILE *stream ); int fclose fprintf<stdio.h> fprintf<stdio.h> Enter the account, name, and balance. Win 95, Win NT a nonzero value after Enter the account, name, and balance. Win 95, Win NT a nonzero value after The feof function returns ANSI, The feof function returns Header Compatibility ANSI, Function Required Header Compatibility Enter EOF to end input. Function Required Enter EOF to end input. the first read operation that attempts to read the first read operation that attempts to read fclose<stdio.h> ? 100 Jones 24.98 fclose of the ? 100 Jones 24.98 past the end<stdio.h> It returns 0 if the Return Value past ANSI,Value file. NTreturns 0 if the the end of 95, file. Return Win the Win It ? 200 Doe 345.67 ANSI, Win not end of ? 200 Doe 345.67 current position istheWin NT file.bytes written. fprintf returns95, number of bytes written. current position isthe number file. There is no fprintf returns not end of of There is no ? 300 White 0.00 ? 300 White 0.00 error return.negative value instead when an Returns a Value errorReturnnegative value instead when an return. Returns a ? 400 Stone -42.16 Return ? 400 Stone -42.16 output errorValue output error occurs occurs ? 500 Rich 224.62 ? 500 Rich 224.62 fclose returns 0 ififthe stream is successfully ? fclose returns 0 the stream is successfully ? closed. Return EOF to indicate an error. closed. Return EOF to indicate an error.

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 11

End Of File Combinations: End Of File Combinations:


In our program the line In our program the line While (!feof (stdin)) While (!feof (stdin)) Uses the function feof to determine whether the end-ofUses the function feof to determine whether the end-offile indicate is set for the file to which stdin refers. file indicate is set for the file to which stdin refers. In this case the feof is set to the standard input, when In this case the feof is set to the standard input, when the user enters the end-of-file key combination. the user enters the end-of-file key combination. The end-of-file combination is platform or system The end-of-file combination is platform or system dependent. dependent. System Key Combination System Key Combination
UNIX UNIX IBM PC IBM PC Macintosh Macintosh <return> <ctrl> d <return> <ctrl> d <ctrl> cc <ctrl> <ctrl> d <ctrl> d
Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 12

cfPtr = fopen (clients.dat, w); cfPtr = fopen (clients.dat, w);

User Has Access to This

Fopen return a pointer to a FILE structure Fopen return a pointer to a FILE structure (defined in <stdio.h> (defined in <stdio.h>

Only the operating system operating system Has access to this: access to this: Open File Table Open File Table 1 1 2 2 3 3 4 4 5 5 6 6 7 7 . . .

FILE structure for FILE structure for

clients.dat clients.dat Contains a descriptor, Contains a descriptor, I.E. a small integer which I.E. a small integer which Is an index into the Is an index into the Open File Table Open File Table

FCB for clients.dat FCB for clients.dat

. . .

7 7
When the program issues an I/O call such as When the program issues an I/O call such as

The program calls an operating The program calls an operating

system service that uses data in the system service that uses data in the FCB to control all input and output to FCB to control all input and output to the actual file on the disk. Note: the the actual file on the disk. Note: the user cannot directly access the FCB. user cannot directly access the FCB.

fprintf (cfPtr, %d %s %.2f, account, name, balance ); fprintf (cfPtr, %d %s %.2f, account, name, balance ); This entry is copied from FCB This entry is copied from FCB The program locates the descriptor (7) in the FILE The program locates the descriptor (7) in the FILE on disk when the file is opened. on disk when the file is opened. structure and uses the descriptor to find the FCB in the structure and uses the descriptor to find the FCB in the Open File Table Open File Table Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 13

Reading Data from a Sequential Reading Data from a Sequential Access File: Access File:
Reading a sequential access file Reading a sequential access file Create a FILE pointer, link it to the file to read Create a FILE pointer, link it to the file to read myPtr = fopen( "myFile.dat", "r" ); myPtr = fopen( "myFile.dat", "r" ); Use fscanf to read from the file Use fscanf to read from the file Like scanf, except first argument is a FILE pointer Like scanf, except first argument is a FILE pointer fscanf( myPtr, "%d%s%f", &myInt, &myString, &myFloat ); fscanf( myPtr, "%d%s%f", &myInt, &myString, &myFloat ); Data read from beginning to end Data read from beginning to end File position pointer --indicates number of next byte to be File position pointer indicates number of next byte to be read/written read/written Not really a pointer, but an integer value (specifies byte Not really a pointer, but an integer value (specifies byte location) location) Also called byte offset Also called byte offset rewind(myPtr) --repositions file position pointer to beginning rewind(myPtr) repositions file position pointer to beginning of the file (byte 0) of the file (byte 0)
Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 14

Reading and Printing Sequential Files: Reading and Printing Sequential Files:

/* Fig. 11.7: fig11_07.c Reading and printing a sequential file */ #include <stdio.h> int main() { int account; char name[ 30 ]; double balance; FILE *cfPtr; /* cfPtr = clients.dat file pointer */

fscanf, fscanf, Read formatted data from a stream. Read formatted data from a stream. int fscanf( FILE *stream, const char *format int fscanf( FILE *stream, const char *format [, argument ]... ); [, argument ]... ); Function Required Header Compatibility Function Required Header Compatibility fscanf<stdio.h> fscanf<stdio.h> ANSI, Win 95, Win NT ANSI, Win 95, Win NT

if ( ( cfPtr = fopen( "clients.dat", "r" ) ) == NULL ) printf( "File could not be opened\n" ); Return Value Return Value else { this functions returns the number of fields this printf( "%-10s%-13s%s\n", "Account", "Name", "Balance" ); functions returns the number of fields successfully converted and assigned; the return fscanf( cfPtr, "%d%s%lf", &account, name, &balance ); successfully converted and assigned; the return value does not include fields that were read but value does not include fields that were read but not assigned. A return value of 0 indicates that while ( !feof( cfPtr ) ) { not assigned. A return value of 0 indicates that Account Name Balance Account Name Balance printf( "%-10d%-13s%7.2f\n", account, name, balance );no fields were assigned. no fields were assigned. 100 Jones 24.98 100 Jones 24.98 fscanf( cfPtr,Doe "%d%s%lf", &account, name, &balance ); 200 345.67 200 Doe 345.67 } 300 White 0.00 300 White 0.00 400 -42.16 400 cfPtr ); Stone Stone -42.16 fclose( Rich 224.62 500 Rich 224.62 }500 } return 0;

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 15

Credit Inquiry Program: Credit Inquiry Program:

/* Fig. 11.8: fig11_08.c Credit inquiry program */ #include <stdio.h> int main() { int request, account; double balance; char name[ 30 ]; FILE *cfPtr; if ( ( cfPtr = fopen( "clients.dat", "r" ) ) == NULL ) printf( "File could not be opened\n" ); else { printf( "Enter request\n" " 1 - List accounts with zero balances\n" " 2 - List accounts with credit balances\n" " 3 - List accounts with debit balances\n" " 4 - End of run\n? " ); scanf( "%d", &request ); while ( request != 4 ) { fscanf( cfPtr, "%d%s%lf", &account, name, &balance );

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 16

Credit Inquiry Program: Credit Inquiry Program:

switch ( request ) { case 1: printf( "\nAccounts with zero " "balances:\n" ); while ( !feof( cfPtr ) ) { if ( balance == 0 ) printf( "%-10d%-13s%7.2f\n", account, name, balance ); fscanf( cfPtr, "%d%s%lf", &account, name, &balance );

break; case 2: printf( "\nAccounts with credit " "balances:\n" ); while ( !feof( cfPtr ) ) { if ( balance < 0 ) printf( "%-10d%-13s%7.2f\n", account, name, balance ); fscanf( cfPtr, "%d%s%lf", &account, name, &balance );

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 17

Credit Inquiry Program: Credit Inquiry Program:

break; case 3: Enter request Enter request printf( "\nAccounts with debit " 11 -- List accounts with zero balances List accounts with zero balances rewind "balances:\n" ); rewind 22 -- List accounts with credit balances Repositions the file pointer to the beginning of List accounts with credit balances Repositions the file pointer to the beginning of while !feof( cfPtr with debit balances 33 -- List ( accounts) )with debit balances a file. List accounts { a file. 44 -- End of run Endbalance > 0 ) of run void rewind( FILE *stream ); void rewind( FILE *stream ); if ( ?? 11 printf( "%-10d%-13s%7.2f\n", account, name, balance ); Routine Required Header Compatibility Routine Required Header Compatibility Accounts with zero balances: Accounts with zero balances: rewind<stdio.h> rewind<stdio.h> fscanf( cfPtr, "%d%s%lf", 0.00 300 White 300 White name, &balance0.00 ANSI, Win 95, Win NT ANSI, Win 95, Win NT &account, ); } ?? 22 Return Value Return Value break; None None } Accounts with credit balances: Accounts with credit balances: 400 Stone -42.16 400 Stone -42.16 rewind( cfPtr ); printf( "\n? " ); scanf( "%d", &request ); ?? 33 } Accounts with debit balances: Accounts of run.\n" ); printf( "End with debit balances: 100 Jones 24.98 fclose( cfPtr );Jones 100 24.98 }200 200 Doe 345.67 Doe 345.67 500 Rich 224.62 500 0; Rich 224.62 return ?? 44 } End of run. End of run.

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 18

Random Access Files: Random Access Files:


Random access files Random access files Access individual records without searching through other Access individual records without searching through other records records Instant access to records in a file Instant access to records in a file Data can be inserted without destroying other data Data can be inserted without destroying other data Data previously stored can be updated or deleted without Data previously stored can be updated or deleted without overwriting. overwriting. Implemented using fixed length records Implemented using fixed length records Sequential files do not have fixed length records Sequential files do not have fixed length records Byte 100 200 300 400 500 Byte 100 200 300 400 500

0 0

Offsets Offsets

100 100 Bytes Bytes

100 100 Bytes Bytes

100 100 Bytes Bytes

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 19

100 100 Bytes Bytes

100 100 Bytes Bytes

100 100 Bytes Bytes

Creating a Random Access File: Creating a Random Access File:


Data Data Data unformatted (stored as "raw bytes") in random Data unformatted (stored as "raw bytes") in random access files access files All data of the same type (ints, for example) use All data of the same type (ints, for example) use the same memory the same memory All records of the same type have a fixed All records of the same type have a fixed length length Data not human readable Data not human readable

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 20

Creating a Random Access File: Creating a Random Access File:


Unformatted I/O functions Unformatted I/O functions fwrite --Transfer bytes from a location in memory to fwrite Transfer bytes from a location in memory to a file a file fread --Transfer bytes from a file to a location in fread Transfer bytes from a file to a location in memory memory fwrite( &number, sizeof( int ), 1, myPtr ); fwrite( &number, sizeof( int ), 1, myPtr ); &number --Location to transfer bytes from &number Location to transfer bytes from sizeof( int ))--Number of bytes to transfer sizeof( int Number of bytes to transfer 1 --For arrays, number of elements to transfer 1 For arrays, number of elements to transfer In this case, "one element" of an array is being In this case, "one element" of an array is being transferred transferred myPtr --File to transfer to or from myPtr File to transfer to or from fread similar fread similar Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 21 Norris

Creating a Random Access File: Creating a Random Access File:


Writing structs Writing structs
fwrite( &myObject, sizeof (struct myStruct), 1, fwrite( &myObject, sizeof (struct myStruct), 1, myPtr ); myPtr ); sizeof --Returns size in bytes of object in parentheses sizeof Returns size in bytes of object in parentheses

To write several array elements To write several array elements Pointer to array as first argument Pointer to array as first argument Number of elements to write as third Number of elements to write as third argument argument
Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 22

Reading Data from a Sequential Reading Data from a Sequential Access File: Access File:
Sequential access file Sequential access file Cannot be modified without the risk of destroying Cannot be modified without the risk of destroying other data other data
300 White 0.00 400 Jones 32.87

(old data in file)

If we want to change White's name to Worthington,


300 Worthington 0.00 300 White 0.00 400 Jones 32.87 300 Worthington 0.00ones 32.87

Data gets overwritten Data gets overwritten

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 23

Creating a Randomly Accessed Files Sequentially: Creating a Randomly Accessed Files Sequentially:

/* Fig. 11.11: fig11_11.c Creating a randomly accessed file sequentially */ #include <stdio.h> struct clientData { int acctNum; char lastName[ 15 ]; char firstName[ 10 ]; double balance; }; int main() { int i; struct clientData blankClient = { 0, "", "", 0.0 }; FILE *cfPtr; if ( ( cfPtr = fopen( "credit.dat", "w" ) ) == NULL ) printf( "File could not be opened.\n" ); else { for ( i = 1; i <= 100; i++ ) fwrite( &blankClient, sizeof( struct clientData ), 1, cfPtr ); } } fclose ( cfPtr );

sizeof Operator sizeof Operator sizeof expression sizeof expression The sizeof keyword gives the amount of The sizeof keyword gives the amount of storage, in bytes, associated with a variable or storage, in bytes, associated with a variable or a type (including aggregate types). This a type (including aggregate types). This keyword returns a value of type size_t. keyword returns a value of type size_t. The expression is either an identifier or a typeThe expression is either an identifier or a typecast expression (a type specifier enclosed in cast expression (a type specifier enclosed in parentheses). parentheses). When applied to a structure type or variable, When applied to a structure type or variable, sizeof returns the actual size, which may sizeof returns the actual size, which may include padding bytes inserted for alignment. include padding bytes inserted for alignment. When applied to a statically dimensioned array, When applied to a statically dimensioned array, sizeof returns the size of the entire array. The sizeof returns the size of the entire array. The sizeof operator cannot return the size of sizeof operator cannot return the size of dynamically allocated arrays or external arrays. dynamically allocated arrays or external arrays.

return 0;

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 24

Writing Data Randomly to a Random Writing Data Randomly to a Random Access File: Access File:
fseek fseek Sets file position pointer to a specific position Sets file position pointer to a specific position fseek(( myPtr, offset, symbolic_constant); fseek myPtr, offset, symbolic_constant); myPtr -- pointer to file myPtr pointer to file offset -- file position pointer (0 is first offset file position pointer (0 is first location) location) symbolic_constant -- specifies where in file symbolic_constant specifies where in file we are reading from we are reading from SEEK_SET -- seek starts at beginning of file SEEK_SET seek starts at beginning of file SEEK_CUR -- seek starts at current location SEEK_CUR seek starts at current location in file in file SEEK_END -- seek starts at end of file SEEK_END seek Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 25 starts at end of file Norris Edwards,

Creating a Randomly Accessed Files: Creating a Randomly Accessed Files:

#include <stdio.h> struct clientData { int acctNum; char lastName[ 15 ]; fseek, fseek, char firstName[ 10 ]; double balance; }; #include <stdio.h> #include <stdio.h> int main() FILE *cfPtr; struct clientData client = { 0, "", "", 0.0 }; Remarks Remarks if ( ( cfPtr = fopen( "credit.dat", "r+" ) ) == NULL ) The origin argument specifies the initial position The origin argument specifies the initial position printf( "File could not be opened.\n" ); else { and can be one of the manifest constants and can be one of the manifest constants printf( account number (1 to 100, 0 to end input) number" Enter "Enter accountend input (1 to 100, 0 to end input) shown below: Enter 1accounttonumber )\n? " ); shown below: " ( to 100, 0 ? 37 "%d", &client.acctNum ); scanf( ? 37 Enter lastname, firstname, balance Constant Meaning Enter client.acctNum != 0 ) { Constant Meaning while ( lastname, firstname, balance ? printf( "Enter lastname, firstname, balance\n? " ); Barker Doug 0.00 ? Barker Doug 0.00 fscanf( stdin, "%s%s%lf", client.lastName, Enter account number SEEK_END End of file Enter account number SEEK_END End of file ? fseek( cfPtr, ( client.acctNum - 1 ) * ); 29 client.firstName, &client.balance SEEK_CUR Current position of file pointer ? 29 SEEK_CUR Current position of file pointer Entersizeof( struct clientData ), SEEK_SET ); SEEK_SET Beginning of file Enter lastname, firstname, balance lastname, firstname, balance SEEK_SET Beginning of file ? fwrite( &client, sizeof( struct clientData ), 1, ? Brown Nancy -24.54 Brown Nancy -24.54 cfPtr ); Enter account number printf( "Enter account number\n? " ); Enter account number ? scanf( "%d", &client.acctNum ); ? 96 } 96 Enter lastname, firstname, balance Enter lastname, firstname, balance fclose( cfPtr ); ? Stone Sam 34.98 ? Stone Sam 34.98 } return 0; }

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 26

Reading Data Sequentially from a Reading Data Sequentially from a Random Access File: Random Access File:
fread fread Reads a specified number of bytes from a file Reads a specified number of bytes from a file into memory into memory fread( &client, sizeof (struct clientData), 1, fread( &client, sizeof (struct clientData), 1, myPtr ); myPtr ); Can read several fixed-size array elements Can read several fixed-size array elements Provide pointer to array Provide pointer to array Indicate number of elements to read Indicate number of elements to read To read multiple elements, specify in third To read multiple elements, specify in third argument argument
Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 27

Reading a Randomly Accessed Files Sequentially: Reading a Randomly Accessed Files Sequentially:

/* Fig. 11.15: fig11_15.c Reading a random access file sequentially */ #include <stdio.h>

struct clientData { int acctNum; char lastName[ 15 ]; char firstName[ 10 ]; double balance; }; Function Required Header Compatibility Function Required Header Compatibility int main() fread<stdio.h> fread<stdio.h> { ANSI, Win 95, Win NT ANSI, Win 95, Win NT FILE *cfPtr; struct clientData client = { 0, "", "", 0.0 }; if ( ( cfPtr = fopen( "credit.dat", "r" ) ) == NULL ) Return Value Return Value printf( "File could not be opened.\n" ); fread returns the number of full items actually fread returns the number of full items actually else { read, which may be less than count if an error printf( "%-6s%-16s%-11s%10s\n", "Acct", "Last Name", read, which may be less than count if an error occurs or if the end of the file is encountered "First Name", "Balance" ); occurs or if the end of the file is encountered while ( !feof( cfPtr ) ) { before reaching count. Use the feof or ferror before reaching count. Use the feof or ferror fread( &client, sizeof( struct clientData ), 1, function to distinguish a read error from an function to distinguish a read error from an cfPtr ); Acct Last Name First Name Balance Acct Last Name ) First Name Balance end-of-file condition. If size or count is 0, fread end-of-file condition. If size or count is 0, fread if ( client.acctNum != 0 29 Brown Nancy -24.54 29 Brown Nancy -24.54 printf( "%-6d%-16s%-11s%10.2f\n", 33 client.acctNum, client.lastName, Dunn Stacey 314.33 33 Dunn Stacey 314.33 37 client.firstName, client.balance ); Barker Doug 0.00 37 Barker Doug 0.00 } 88 Smith Dave 258.34 88 cfPtr ); Smith Dave 258.34 fclose( Stone Sam 34.98 96 Stone Sam 34.98 } 96 return 0; }

Notice that the client.dat file is opened in Notice that the client.dat file is opened in fread fread read mode (r) in this case. read mode (r) in this case. Reads data from a stream. Reads data from a stream. size_t fread( void *buffer, size_t size, size_t fread( void *buffer, size_t size, size_t count, FILE *stream ); size_t count, FILE *stream );

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 28

File Positions Pointer indicating an offset File Positions Pointer indicating an offset of 5 bytes from the beginning of the file: of 5 bytes from the beginning of the file:
cfPtr

5
Byte Number 0 0 1 1 2 2 3 3

(File Position Pointer)

4 4

5 5

6 6

7 7

8 8

9 9

10 10

n Byte n Byte Offsets Offsets

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 29

A Transaction Processing Program: A Transaction Processing Program:


Uses random access files to achieve instant access Uses random access files to achieve instant access processing of a banks account information processing of a banks account information We will We will Update existing accounts Update existing accounts Add new accounts Add new accounts Delete accounts Delete accounts Store a formatted listing of all accounts in a text file Store a formatted listing of all accounts in a text file

Menu Menu Update Update Add Add Delete Delete Text Text

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 30

A Transaction Processing Program: A Transaction Processing Program:


/* Fig. 11.16: fig11_16.c This program reads a random access file sequentially, updates data already written to the file, creates new Declares the clientData structure. Declares the clientData structure. data to be placed in the file, and deletes data already in the file. */ #include <stdio.h> struct clientData { int acctNum; char lastName[ 15 ]; char firstName[ 10 ]; double balance; }; int enterChoice( void ); void textFile( FILE * ); void updateRecord( FILE * ); void newRecord( FILE * ); void deleteRecord( FILE * ); int main() { FILE *cfPtr; int choice; if ( ( cfPtr = fopen( "credit.dat", "r+" ) ) == NULL ) printf( "File could not be opened.\n" ); else {

Declares the Declares the TextFile TextFile UpdateRecord UpdateRecord NewRecord NewRecord DeleteRecord DeleteRecord Functions Functions Opens the credit.dat file in read mode. Opens the credit.dat file in read mode.

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 31

A Transaction Processing Program: A Transaction Processing Program:


while ( ( choice = enterChoice() ) != 5 ) { switch ( choice ) { case 1: textFile( cfPtr ); break; case 2: updateRecord( cfPtr ); break; case 3: newRecord( cfPtr ); break; case 4: deleteRecord( cfPtr ); break; } Notice the use of the case structure to Notice the use of the case structure to allow the user to select the option they allow the user to select the option they wish. wish. That choice then invokes the proper That choice then invokes the proper function call. function call.

} } }

fclose( cfPtr );

return 0;

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 32

A Transaction Processing Program: A Transaction Processing Program:


void textFile( FILE *readPtr ) { FILE *writePtr; struct clientData client = { 0, "", "", 0.0 };

Notice that the client.dat file is opened in Notice that the client.dat file is opened in write mode (w) in this case. write mode (w) in this case.

if ( ( writePtr = fopen( "accounts.txt", "w" ) ) == NULL ) printf( "File could not be opened.\n" ); else { rewind( readPtr ); fprintf( writePtr, "%-6s%-16s%-11s%10s\n", "Acct", "Last Name", "First Name","Balance" ); while ( !feof( readPtr ) ) { fread( &client, sizeof( struct clientData ), 1, readPtr ); if ( client.acctNum != 0 ) fprintf( writePtr, "%-6d%-16s%-11s%10.2f\n", client.acctNum, client.lastName, client.firstName, client.balance ); fclose( writePtr );

} } }

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 33

A Transaction Processing Program: A Transaction Processing Program:


void updateRecord( FILE *fPtr ) { int account; double transaction; struct clientData client = { 0, "", "", 0.0 }; printf( "Enter account to update ( 1 - 100 ): " ); scanf( "%d", &account ); fseek( fPtr, ( account - 1 ) * sizeof( struct clientData ), SEEK_SET ); fread( &client, sizeof( struct clientData ), 1, fPtr ); if ( client.acctNum == 0 ) printf( "Acount #%d has no information.\n", account ); else { printf( "%-6d%-16s%-11s%10.2f\n\n", client.acctNum, client.lastName, client.firstName, client.balance ); printf( "Enter charge ( + ) or payment ( - ): " ); scanf( "%lf", &transaction ); client.balance += transaction; printf( "%-6d%-16s%-11s%10.2f\n", client.acctNum, client.lastName, client.firstName, client.balance ); fseek( fPtr, ( account - 1 ) * sizeof( struct clientData ), SEEK_SET ); fwrite( &client, sizeof( struct clientData ), 1, fPtr ); }

Notice the use of the (account-1) offset to Notice the use of the (account-1) offset to convert the computer beginning point (0) convert the computer beginning point (0) to a logical starting point 1. to a logical starting point 1.

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 34

A Transaction Processing Program: A Transaction Processing Program:


void deleteRecord( FILE *fPtr ) { struct clientData client, blankClient = { 0, "", "", 0 }; int accountNum; printf( "Enter account number to " "delete ( 1 - 100 ): " ); scanf( "%d", &accountNum ); fseek( fPtr, ( accountNum - 1 ) * sizeof( struct clientData ), SEEK_SET ); fread( &client, sizeof( struct clientData ), 1, fPtr ); if ( client.acctNum == 0 ) printf( "Account %d does not exist.\n", accountNum ); else { fseek( fPtr, ( accountNum - 1 ) * sizeof( struct clientData ), SEEK_SET ); fwrite( &blankClient, sizeof( struct clientData ), 1, fPtr ); }

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 35

A Transaction Processing Program: A Transaction Processing Program:


void newRecord( FILE *fPtr ) { struct clientData client = { 0, "", "", 0.0 }; int accountNum; printf( "Enter new account number ( 1 - 100 ): " ); scanf( "%d", &accountNum ); fseek( fPtr, ( accountNum - 1 ) * sizeof( struct clientData ), SEEK_SET ); fread( &client, sizeof( struct clientData ), 1, fPtr ); if ( client.acctNum != 0 ) printf( "Account #%d already contains information.\n", client.acctNum ); else { printf( "Enter lastname, firstname, balance\n? " ); scanf( "%s%s%lf", &client.lastName, &client.firstName, &client.balance ); client.acctNum = accountNum; fseek( fPtr, ( client.acctNum - 1 ) * sizeof( struct clientData ), SEEK_SET ); fwrite( &client, sizeof( struct clientData ), 1, fPtr ); }

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 36

A Transaction Processing Program: A Transaction Processing Program:


int enterChoice( void ) { This is a good example of how to set up a int menuChoice; This is a good example of how to set up a After choosing option 1 accounts.txtuser menu. Notice that menu references contains: After choosing option 1 accounts.txtuser menu. Notice that menu references contains: printf( "\nEnter your choice\n" the switch/case structure in order to the switch/case structure in order to "1 - Last Name acounts called\n" Balance Acct store a formatted text file ofFirst Name First Name Acct Last Name printing\n" Balance cause the program to branch properly. cause the program to branch properly. " \"accounts.txt\" for 29 - update an account\n" Brown Nancy -24.54 29 Brown Nancy -24.54 "2 33 - add a new account\n" Dunn Stacey 314.33 "3 33 Dunn Stacey 314.33 "4 37 - delete an account\n" Barker Doug 0.00 37 Barker Doug 0.00 "5 - end program\n? " ); 88 Smith Dave 258.34 88 Smith 258.34 scanf( "%d", &menuChoice ); Dave 96 menuChoice; Stone Sam 34.98 96 Sam 34.98 return Stone } Enter account to update (1 - 100): 37 Enter account to update (1 - 100): 37 37 Barker Doug 37 Barker Doug 0.00 0.00

Enter charge (+) or payment (-): +87.99 Enter charge (+) or payment (-): +87.99 37 Barker Doug 87.99 37 Barker Doug 87.99

Enter new account number (1 - 100): 22 Enter new account number (1 - 100): 22 Enter lastname, firstname, balance Enter lastname, firstname, balance ? Johnston Sarah 247.45 ? Johnston Sarah 247.45

Norris Edwards, Deitel and Deitel, Chapter 11, Deitel11.ppt: Page: 37

You might also like