Professional Documents
Culture Documents
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
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
Byte Byte
File File
1 1
0 0
1 1
2 2
3 3
4 4
5 5
8 8
7 7
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 );
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.
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 . . .
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
. . .
7 7
When the program issues an I/O call such as When the program issues an I/O call such as
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;
/* 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 );
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 );
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.
0 0
Offsets Offsets
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
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;
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,
#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; }
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 );
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
4 4
5 5
6 6
7 7
8 8
9 9
10 10
Menu Menu Update Update Add Add Delete Delete Text Text
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.
} } }
fclose( cfPtr );
return 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 );
} } }
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.
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