Fall 2013 CE - 102 Computer Programming & Problem Solving CPPS

Handling Filing in C Language Chapter No 5

Files A permanent method of storing data

Records 121 Sam Jones 80 95 82 143 Jane Albright 75 92 84 etc.

File Students.txt

Files = Directory Directory = related files

Files „ „ „ „

Collection of data under 1 name Multiple records = file File name - Max 8 characters 3 Character extension

Data Hierarchy „

Byte „

„

Field „

„

Composed of related fields (struct)

File „

„

Group of characters (character string “Fred”)

Record „

„

8 bits (ASCII character ‘A’ = 01000001)

Group of related records (student record file)

Database „

Group of related files (students, faculty, and staff files)

Opening a file „ „

Create a link from file to program Equates external name to internal

Fopen() „ „ „

2 arguments (1) Name for the file (2) Mode - R, W, A

Basic Filing Modes „ „ „

R = read W = write A = append

Filing Modes „

r

„

Open a file for reading

„

„

„

„

„

w „

Open or create a file for writing If file already exists, erase the contents

„

Append: open or create a file Write to the end of the file

„

„

Open a file for update (reading & writing)

w+ „

„

a „

r+

Open or create a file for update Erase contents of existing file

a+ „

„

Append: open or create a file for update All writing done at end of file

Writing „ „ „ „

Creates new file Available for output Old file present - erased out_file = fopen("prices.txt","w");

Text & Binary Files „

Text files „ „ „ „

„

Store ASCII characters (ex: 32 = 00110011 00110010) ASCII uses only 7 bits, 8th bit is for error control Easy to read, but take up more space Examples: file.txt, file.html

Binary files „ „ „

Store numbers (ex: 32 = 100000) Compact, but more complex to read Examples: file.gif, file.exe

Internal name „ „

out_file - name used to access file File saved under prices.txt

Append „

Data written to end of file

Read mode „ „ „ „

Data available for input Can read data into program in_file=fopen("prices.txt","r"); File not found = returns null

Testing for file not found „ „ „ „

in_file=fopen("data.txt","r"); if(in_file == null) { printf("file not there"); exit(1); }

Exit(1) „ „

Passes control to operating system Terminates the program

Closing a file „ „ „ „

fclose(in_file); Breaks the link to program Program termination - files automatically closed

Need to close files „ „

Limited # can be open Closing frees up a file

More File Functions „

int feof(FILE *fp) „ „

„

Returns non-zero, if end-of-file Returns 0, if not end-of-file

int fclose(FILE *fp) „ „ „

Closes a file Returns 0, if successful; EOF, if not Will be done automatically after a program finishes executing

Writing to a File „

„

„

int fputc(int ch, FILE *fp) „ Writes one character to a file „ If successful, returns the character; if not, returns EOF int fputs(char *str, FILE *fp) „ Writes str to a file „ Returns a nonnegative value or EOF for error „ Does not append a \n int fprintf(FILE *fp, const char *format, arg1, arg2,… ) „ Same as printf function

Reading from a File „

„

„

int fgetc(FILE *fp) „ Reads one character from a file & returns it char *fgets(char *str, int max, FILE *fp) „ Reads a line from a file „ Puts the characters (including \n) and \0 in str „ Max is the maximum number of characters to be written to the string int fscanf(FILE *fp, const char *format, arg1, arg2,… ) „ Same as scanf function

Rereading a File „

„

Once a file is read, the file position pointer is at the end of the file File position pointer „ „ „ „

„

Actually an integer value Byte location in file for next read or write Also called file offset Part of FILE structure

int rewind (FILE *fp) „

Reposition to beginning of file (byte 0)

What Does This Program Do? int main(){ FILE *fp; char ch='\0'; int i = 0; if((fp = fopen("file.txt","r"))==NULL) printf("File could not be opened\n"); while((ch=fgetc(stdin))!=EOF) { while(!feof(fp)) if(ch==fgetc(fp)) i++; if(ch != '\n') printf("%d\n", i); rewind(fp); } close(fp); } return 0; }

Fputc „ „

fputc('r',filename); Write a single character to file

else{

i=0;

Fputs „ „

fputs(string,filename) Write a string to file

Fprintf „ „

fprintf(filename,"format",args); fprintf(out_file,"%s%d",desc,price);

Examples „ „

„

fputc('a',out_file); /* write chr */ fputs("hello",out_file); /* write string */ fprintf(out_file,"%f",val2);

Sequential vs Random access „ „ „

Sequential - read from top in order Random access - Read in any order Random requires a key

File data type „ „ „ „ „

FILE *infile FILE *outfile * = pointer to a file Pointer necessary as file not part of the C program

Standard file pointers „ „ „ „

Built in to C in stdio.h FILE *stdin /* std input */ FILE *stdout /* std output */ FILE *stderr /* std error */

Stanard error „ „

Place where error messages are sent Usually the terminal screen

Opening a file „ „ „

„

infile = fopen("testdata", "r"); Both arguments are strings First = name as known to operating system Second = mode - r, w, a

Output „ „ „ „

outfile = fopen("outdata","w"); outfile = fopen("outdata","a"); Append - preserves existing data If no outfile - will be created

Closing a file „ „ „

Limited # of files available FOPEN_MAX has # files available Will be closed automatically by OS

Getting data from a file „ „ „ „

fscanf(infile, "%c", &next_char); Read a character from infile Store it in next_char Like scanf - with pointer to a file

Writing to a file „ „ „

fprintf(outfile, "%c", next_char); Like printf - with file pointer Store next_char in outfile

End of file „ „ „

Terminates the data Written when the file is closed Can check for the end of data

Checking for end of file „ „

„

int flag; flag = fscanf(infile, "%c", &next_char); while (EOF != flag)

Null pointer „ „ „ „

If file cannot be opened Must test for this condition if(NULL == infile) printf("find the file Bozo");

File position indicator „ „ „ „

Open to read - beginning of file fscanf - advances position indicator Go back to beginning - close - open Or rewind(infile);

Reading fgets „ „ „

Read n-1 characters from file fgets(message,10,infile); Read 9 characters into message

Reading fscanf „ „ „

fscanf(infile,"%f",&price); Read a floating point # Read from infile

End of file „ „ „ „

fgetc & fscanf - return EOF fgets - returns null - \0 != EOF != NULL

Random access „ „ „ „

fseek(infile,offset,origin); Pointer to file Offset as a long integer Where to calculate from for offset

Fseek examples „ „ „ „

fseek(infile,4L,0); Go to 5th character in file fseek(infile,4L,1); Move ahead 5 characters

Origin values „ „ „

0 - true offset - start of file 1 - Offset relative to current position 2 - Origin relative to EOF

Random-Access Files „

Random-access files „ Individual records are fixed in length „ Can be accessed directly without searching though other records „ Much quicker to access data „ Use record key to find distance from beginning of file „ Update & delete data without overwriting other data in the file

Creating „

„

Function fwrite() sends a block of memory to the specified file size_t fwrite(void *buffer, size_t size, size_t num, FILE *fp); „ buffer = start of memory „ size = size of each chunk of memory (in bytes) „ num = number of chunks of memory (in bytes) „ fp = the file to send the memory to „ Returns the number of chunks written

/*Creating a file for 100 fixed-length records*/ #include struct client{ int acctNum; char lastName[15]; char firstName[10]; double balance; }; int main() { int i; struct client blank = { 0, "", "", 0.0 }; FILE *fp; if ((fp=fopen("credit.txt","w"))==NULL) printf("File could not be opened.\n"); else { for ( i = 1; i <= 100; i++ ) fwrite(&blank,sizeof(struct client),1,fp); fclose(fp); } return 0;} //See create.c

Writing Data „

Use fseek() to position the file position pointer „ int fseek(FILE *stream, long int offset, int whence) „ „

stream = file pointer offset = number of bytes from “whence” „ whence = „ SEEK_SET (beginning of file) „ SEEK_CUR (current location) „ SEEK_END (end of file)

/*Writing to a file*/ FILE *fp; struct client temp = { 0, "", "", 0.0 }; if ((fp = fopen("credit.txt","r+"))==NULL) /*note: using "w" will overwrite the data*/ printf("File could not be opened.\n"); else { printf("Enter account number (1 to 100):"); scanf( "%d", &temp.acctNum ); while ( temp.acctNum != 0 ) { printf("Enter last, first & balance: "); scanf("%s%s%lf", temp.lastName, temp.firstName, &temp.balance ); fseek(fp,( temp.acctNum - 1 ) * sizeof( struct client ), SEEK_SET ); fwrite(&temp,sizeof(struct client),1,fp); printf( "Enter account number:" ); scanf( "%d", &temp.acctNum ); } fclose( fp );} //See writing.c

Reading Data „

Use fread() to read a specific number of bytes from a file into memory „ size_t fread(void *buffer, size_t size, size_t num, FILE *fp); „ „ „ „ „

buffer = start of memory size = size of each chunk of memory (in bytes) num = number of chunks of memory (in bytes) fp = the file from which the memory is read Returns the number of chunks written

/*Reading from a file*/ FILE *fp; struct client temp = { 0, "", "", 0.0 }; if((fp=fopen("credit.txt","r"))==NULL) printf("File could not be opened.\n" ); else { printf( "%-6s%-16s%-11s%10s\n", "Acct", "Last Name","First Name", "Balance" ); while(!feof(fp)){ fread(&temp,sizeof(struct client),1,fp ); if(temp.acctNum!=0) printf("%-6d%-16s%11s%10.2f\n", temp.acctNum, temp.lastName, temp.firstName, temp.balance ); } fclose(fp); } //See reading.c

Updating a Record „

„

Ask the user for the record for updating printf("Enter account to update (1-100):"); scanf( "%d", &account ); Adjust the file position pointer & read the data into temp fseek( fp,( account - 1 ) * sizeof( struct client ), SEEK_SET ); fread( &temp, sizeof( struct client ), 1, fp );

Updating a Record „

„

Check to see if record exists or not if ( temp.acctNum == 0 ) printf("Acount #%d has no information.\n", account ); If so, display to screen else { printf( "%-6d%-16s%-11s%10.2f\n\n", temp.acctNum, temp.lastName, temp.firstName, temp.balance );

Updating a Record „

„

Ask user for deposit or withdrawal printf( "Enter charge ( + ) or payment ( - ): " ); scanf( "%lf", &transaction ); temp.balance += transaction; Write new data to file fseek( fp, ( account - 1 ) * sizeof( struct client ), SEEK_SET ); fwrite( &temp, sizeof( struct client ), 1, fp );

Deleting a Record „

„

Ask the user for the record for deleting printf("Enter account to delete (1-100):"); scanf( "%d", &account ); Adjust the file position pointer & read the data into temp fseek( fp,( account - 1 ) * sizeof( struct client ), SEEK_SET ); fread( &blank, sizeof( struct client ), 1, fp );

Deleting a Record „

Check to see if record exists or not if ( temp.acctNum == 0 ) printf("Acount #%d has no information.", account );

„

If so, delete it (write over it with empty record) else { fseek( fp, ( accountNum - 1 ) * sizeof( struct client ), SEEK_SET ); fwrite(&blank, sizeof(struct client), 1, fp ); }

File usage „ „ „ „ „

Permanent data storage Back up of data Sharing data Combinig data sources Extracting pertinant data

Random access „ „ „ „

Need a unique key for access Hash code for uniqueness Combine various elements into key Bell790gato

Network file access „ „ „ „

Can be slow - transmission latency Faster links Replicate data Compress data

Creating a Random Access File „

Writing structs fwrite( &myObject, sizeof (struct myStruct), 1, myPtr ); „

„

sizeof – returns size in bytes of object in parentheses

To write several array elements „ Pointer to array as first argument „ Number of elements to write as third argument

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

/* Fig. 11.11: fig11_11.c Creating a randomly accessed file sequentially */ #include 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 );

1. Define struct 1.1 Initialize variable 1.2 Initialize struct 2. Open file 2.1 Write to file using unformatted output 3. Close file

fclose( cfPtr ); } return 0; }

Writing Data Randomly to a Random Access File „

fseek „ „

Sets file position pointer to a specific position fseek( pointer, offset, symbolic_constant ); „ pointer – pointer to file „ offset – file position pointer (0 is first location) „ symbolic_constant – specifies where in file we are reading from „ „ „

SEEK_SET – seek starts at beginning of file SEEK_CUR – seek starts at current location in file SEEK_END – seek starts at end of file

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

/* Fig. 11.12: fig11_12.c Writing to a random access file */ #include struct clientData { int acctNum; char lastName[ 15 ]; char firstName[ 10 ]; double balance; };

1. Define struct 1.1 Initialize variables 2. Open file

int main() { FILE *cfPtr; struct clientData client = { 0, "", "", 0.0 }; if ( ( cfPtr = fopen( "credit.dat", "r+" ) ) == NULL ) printf( "File could not be opened.\n" ); else { printf( "Enter account number" " ( 1 to 100, 0 to end input )\n? " ); scanf( "%d", &client.acctNum );

2.1 Input data 2.2 Write to file

while ( client.acctNum != 0 ) { printf( "Enter lastname, firstname, balance\n? " ); fscanf( stdin, "%s%s%lf", client.lastName, client.firstName, &client.balance ); fseek( cfPtr, ( client.acctNum - 1 ) * sizeof( struct clientData ), SEEK_SET ); fwrite( &client, sizeof( struct clientData ), 1, cfPtr ); printf( "Enter account number\n? " );

3. Close file 33

scanf( "%d", &client.acctNum );

34

}

35 36 37

Program Output

fclose( cfPtr ); }

38 39

return 0;

40 }

Enter account number (1 to ? 37 Enter lastname, firstname, ? Barker Doug 0.00 Enter account number ? 29 Enter lastname, firstname, ? Brown Nancy -24.54 Enter account number ? 96 Enter lastname, firstname, ? Stone Sam 34.98

100, 0 to end input) balance

balance

balance

Enter account number ? 88 Enter lastname, firstname, balance ? Smith Dave 258.34 Enter account number ? 33 Enter lastname, firstname, balance ? Dunn Stacey 314.33 Enter account number ? 0

Program Output

Reading Data Sequentially from a Random Access File „

fread „ Reads a specified number of bytes from a file into memory fread( &client, sizeof (struct clientData), 1, myPtr ); „ Can read several fixed-size array elements „ Provide pointer to array „ Indicate number of elements to read „ To read multiple elements, specify in third argument

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

/* Fig. 11.15: fig11_15.c Reading a random access file sequentially */ #include struct clientData { int acctNum; char lastName[ 15 ]; char firstName[ 10 ]; double balance; };

1. Define struct 1.1 Initialize variables 2. Read (fread)

int main() { FILE *cfPtr; struct clientData client = { 0, "", "", 0.0 };

2.1 Print

if ( ( cfPtr = fopen( "credit.dat", "r" ) ) == NULL ) printf( "File could not be opened.\n" ); else { printf( "%-6s%-16s%-11s%10s\n", "Acct", "Last Name", "First Name", "Balance" ); while ( !feof( cfPtr ) ) { fread( &client, sizeof( struct clientData ), 1, cfPtr ); if ( client.acctNum != 0 ) printf( "%-6d%-16s%-11s%10.2f\n", client.acctNum, client.lastName, client.firstName, client.balance ); }

3. Close file Program Output 33 34 35 36 37 }

Acct 29 33 37 88 96

fclose( cfPtr ); } return 0;

Last Name Brown Dunn Barker Smith Stone

First Name Nancy Stacey Doug Dave Sam

Balance -24.54 314.33 0.00 258.34 34.98

Case Study: A Transaction Processing Program „

This program „

„

We will „ „ „ „

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

Demonstrates using random access files to achieve instant access processing of a bank’s account information Update existing accounts Add new accounts Delete accounts Store a formatted listing of all accounts in a text file

/* Fig. 11.16: fig11_16.c This program reads a random access file sequentially, updates data already written to the file, creates new data to be placed in the file, and deletes data already in the file. */ #include 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 { while ( ( choice = enterChoice() ) != 5 ) { switch ( choice ) {

1. Define struct 1.1 Function prototypes 1.2 Initialize variables 1.3 Link pointer and open file 2. Input choice

33 case 1: 34 textFile( cfPtr ); 35 break; 36 case 2: 37 updateRecord( cfPtr ); 38 break; 39 case 3: 40 newRecord( cfPtr ); 41 break; 42 case 4: 43 deleteRecord( cfPtr ); 44 break; 45 } 46 } 47 48 fclose( cfPtr ); 49 } 50 51 return 0; 52 } 53 54 void textFile( FILE *readPtr ) 55 { 56 FILE *writePtr; 57 struct clientData client = { 0, "", "", 0.0 }; 58 59 if ( ( writePtr = fopen( "accounts.txt", "w" ) ) == NULL ) 60 printf( "File could not be opened.\n" ); 61 else { 62 rewind( readPtr ); 63 fprintf( writePtr, "%-6s%-16s%-11s%10s\n", 64 "Acct", "Last Name", "First Name","Balance" );

65 66 while ( !feof( readPtr ) ) { 67 fread( &client, sizeof( struct clientData ), 1, 68 readPtr ); 69 70 if ( client.acctNum != 0 ) 71 fprintf( writePtr, "%-6d%-16s%-11s%10.2f\n", 72 client.acctNum, client.lastName, 73 client.firstName, client.balance ); 74 } 75 76 fclose( writePtr ); 77 } 78 79 } 80 81 void updateRecord( FILE *fPtr ) 82 { 83 int account; 84 double transaction; 85 struct clientData client = { 0, "", "", 0.0 }; 86 87 printf( "Enter account to update ( 1 - 100 ): " ); 88 scanf( "%d", &account ); 89 fseek( fPtr, 90 ( account - 1 ) * sizeof( struct clientData ), 91 SEEK_SET ); 92 fread( &client, sizeof( struct clientData ), 1, fPtr ); 93 94 if ( client.acctNum == 0 ) 95 printf( "Acount #%d has no information.\n", account ); 96 else {

2.1 Perform action 3. Close file 3.1 Function definitions

3.1 Function definitions

97 printf( "%-6d%-16s%-11s%10.2f\n\n", 98 client.acctNum, client.lastName, 99 client.firstName, client.balance ); 100 printf( "Enter charge ( + ) or payment ( - ): " ); 101 scanf( "%lf", &transaction ); 102 client.balance += transaction; 103 printf( "%-6d%-16s%-11s%10.2f\n", 104 client.acctNum, client.lastName, 105 client.firstName, client.balance ); 106 fseek( fPtr, 107 ( account - 1 ) * sizeof( struct clientData ), 108 SEEK_SET ); 109 fwrite( &client, sizeof( struct clientData ), 1, 110 fPtr ); 111 } 112 } 113 114 void deleteRecord( FILE *fPtr ) 115 { 116 struct clientData client, 117 blankClient = { 0, "", "", 0 }; 118 int accountNum; 119 120 printf( "Enter account number to " 121 "delete ( 1 - 100 ): " ); 122 scanf( "%d", &accountNum ); 123 fseek( fPtr, 124 ( accountNum - 1 ) * sizeof( struct clientData ), 125 SEEK_SET ); 126 fread( &client, sizeof( struct clientData ), 1, fPtr );

127 128 if ( client.acctNum == 0 ) 129 printf( "Account %d does not exist.\n", accountNum ); 130 else { 131 fseek( fPtr, 132 ( accountNum - 1 ) * sizeof( struct clientData ), 133 SEEK_SET ); 134 fwrite( &blankClient, 135 sizeof( struct clientData ), 1, fPtr ); 136 } 137 } 138 139 void newRecord( FILE *fPtr ) 140 { 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156

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 );

3.1 Function definitions

3.1 Function definitions

157

client.acctNum = accountNum;

158

fseek( fPtr, ( client.acctNum - 1 ) *

159

sizeof( struct clientData ), SEEK_SET );

160

fwrite( &client,

161

3.1 Function definitions

sizeof( struct clientData ), 1, fPtr );

162

}

163 } 164 165 int enterChoice( void ) 166 { 167

int menuChoice;

168 169

printf( "\nEnter your choice\n"

170

"1 - store a formatted text file of acounts called\n"

171

"

172

"2 - update an account\n"

173

"3 - add a new account\n"

174

"4 - delete an account\n"

\"accounts.txt\" for printing\n"

175

"5 - end program\n? " );

176

scanf( "%d", &menuChoice );

177

return menuChoice;

178 }

After choosing option 1 accounts.txt contains: Acct 29 33 37 88 96

Last Name Brown Dunn Barker Smith Stone

First Name Nancy Stacey Doug Dave Sam

Balance -24.54 314.33 0.00 258.34 34.98

Enter account to update (1 - 100): 37 37 Barker Doug

0.00

Enter charge (+) or payment (-): +87.99 37 Barker Doug 87.99 Enter new account number (1 - 100): 22 Enter lastname, firstname, balance ? Johnston Sarah 247.45

Program Output

Fall 2013

&next_char);. ▫ while (EOF != flag) ..... 29 Brown. Nancy. -24.54. 33 Dunn. Stacey. 314.33. 37 Barker. Doug. 0.00. 88 Smith. Dave. 258.34. 96. Stone. Sam. 34.98 ...

266KB Sizes 1 Downloads 311 Views

Recommend Documents

No documents