400 likes | 524 Views
4 – File Processing. Opening a File. Declare a file pointer: FILE *fp; Assign to a the file pointer: fp = fopen("clients.dat", "w"); Function prototype: FILE *fopen(char *name, char *mode);. fopen() Modes.
E N D
Opening a File • Declare a file pointer: FILE *fp; • Assign to a the file pointer: fp = fopen("clients.dat", "w"); • Function prototype: FILE *fopen(char *name, char *mode);
fopen() Modes Mode Meaning"r" open text file for reading"w" open text file for writing. If the file already exists, discard the contents."a" open text file for appending
Reading and Writing • of text files • reading and writing will be sequential • Writing • clients.dat • Reading
Writing /* write sequentially to clients.dat */ #include <stdio.h>int main(){ int acc; char name[10]; float bal;FILE *cfptr; if ((cfptr = fopen("clients.dat","w")) == NULL) printf("File could not be opened\n"); else { : continued
printf("Enter acc, name, & bal.\n? "); scanf("%d%s%f", &acc, name, &bal); while (!feof(stdin)) {fprintf(cfptr, "%d %s %.2f\n", acc, name, bal); printf("? "); scanf("%d%s%f", &acc, name, &bal); }fclose(cfptr);}return 0; }
clients.dat 1 Davison 23.672 Paun0.03356 Mason 89.0145 Jackson 11.00 :
Reading /* read sequentially from clients.dat */#include <stdio.h>int main(){ int acc; char name[10]; float bal; FILE *cfptr; if((cfptr = fopen("clients.dat", "r")) == NULL) printf("File could not be opened\n"); else { : continued
printf("Acc Name Bal\n");fscanf(cfptr, "%d %s %f", &acc, name, &bal); while(!feof(cfptr)) { printf("%d %s %f\n", acc,name,bal);fscanf(cfptr, "%d %s %f", &acc, name, &bal); } fclose(cfptr); } return 0;}
Example: Double Space a File • Call: $ dbl_space file1 file2 • dbl_space.c • double_space() • prn_info() • A Graceful fopen()
dbl_space.c #include <stdio.h>#include <stdlib.h>void double_space(FILE *, FILE *);void prn_info(char *);int main(int argc, char *argv[]){ FILE *ifp, *ofp; if (argc != 3){ prn_info(argv[0]); exit(1); } : continued
ifp = fopen(argv[1], "r"); /* read */ ofp = fopen(argv[2], "w"); /* write */ double_space(ifp, ofp); fclose(ifp); fclose(ofp); return 0;}
double_space() void double_space(FILE *ifp, FILE *ofp){ int c; while ((c = getc(ifp)) != EOF) {putc(c, ofp); if (c == ' ')putc(' ', ofp); /* found space -- double it */ }}
prn_info() void prn_info(char *pgn_name)/* version 1 */{printf("\nUsage: %s infile outfile\n", pgn_name); } void prn_info(char *pgn_name)/* version 2 */{fprintf(stderr, "\nUsage: %s inf outf\n", pgn_name);}
A Graceful fopen() FILE *gfopen(char *file_name, char *mode){ FILE *fp; if ((fp = fopen(file_name, mode)) == NULL) {fprintf(stderr, "\nCannot open %s\n", file_name);exit(1); } return fp;}
Random Access • Insertion Problem • How to do Random Access • Binary Files • fwrite() • Creation Program • fseek() • Manipulation Program • fread() • Printing Program
Insertion Problem • clients.dat: 0 White 12.5630 Davison 2345.7832 Deitel 0.00 : 1002 Paun 0.0323 White 12.5135 Brown 1.45 • insertion using sequential read/write is very expensive
acctnum lastname firstname bal 12.27 1 Davison Andrew 2 White Jim 3.24 3 Brown Mary 23.67 :: :: :: :: 100 Wai Loke Seng 4.45 How to do Random Access Creation Program • Create a binary file called creditaccount.datusing fwrite() where each entry is a fixed length.
Manipulation Program • Use fseek() with acctnumto go to an entry immediately.
Binary Files • A binary file stores the system's internal representation of C data structures. • fopen() modes must include a "b": "rb", "wb", "ab", etc.
fwrite() • Informally: fwrite( <pointer to data being inserted>, <size of the data type>, <number of data items being inserted>, <file pointer>) • Example: fwrite( &blankclient, sizeof(struct clientdata), 1, cfptr);
Creation Program /* create 100 empty clients in clientaccount.dat */#include <stdio.h>struct clientdata { int acctnum; char lastname[15]; /* size specified */ char firstname[10]; /* size specified */ float balance;};: continued
int main(){ int i; struct clientdata blankclient = {0, "", "", 0.0}; FILE *cfptr; if ((cfptr =fopen("creditaccount.dat", "wb"))==NULL) printf("File could not be opened.\n"); else { : continued
for (i = 1; i <= 100; i++) fwrite( &blankclient, sizeof(struct clientdata), 1, cfptr); fclose (cfptr); } return 0;}
fseek() • Function prototype: int fseek(FILE *fp, long int offset, int whence); • offsetis the position of the entry. • In this case, it is: (acctnum of entry - 1) * size of an entry
whenceis a symbolic constant indicating the starting position for a seek: SEEK_SET beginning of fileSEEK_CUR current location in fileSEEK_END end of file
Manipulation Program /* insert client info for a specified accnum into creditaccount.dat */#include <stdio.h>#include <string.h>struct clientdata { int acctnum; char last[15]; char first[10]; float bal;}; : continued
int main(){ FILE *cfptr; struct clientdata client; if ((cfptr =fopen("creditaccount.dat", "rb+")) == NULL) printf("File could not be opened.\n"); else { : continued
scanf("%d%s%s%f", &client.acctnum, client.last, client.first, &client.bal);fseek(cfptr, (client.acctnum - 1) * sizeof(struct clientdata), SEEK_SET); fwrite(&client, sizeof(struct clientdata), 1, cfptr); } fclose(cfptr); return 0;}
fread() • Informally: fread( <pointer to data structure for holding extracted data>, <size of the data type>, <number of data items>, <file pointer>) • Example: fread( &client, sizeof(struct clientdata), 1, cfptr);
Printing Program /* print out creditaccount.dat */#include <stdio.h>#include <string.h>struct clientdata { int acctnum; char last[15]; char first[10]; float bal;}; : continued
int main(){ FILE *cfptr; struct clientdata client; if ((cfptr = fopen("creditaccount.dat","rb")) == NULL) printf("File could not be opened.\n"); else { : continued
printf("Acct Lastname Firstname Balance\n"); while (!feof(cfptr)) {fread(&client, sizeof(struct clientdata), 1, cfptr); if (strcmp(client.last, "") != 0) printf("%d %s %s %f\n", client.acctnum, client.last, client.first, client.bal); } } fclose(cfptr); return 0;}
Text Files and Binary Files Compared • Example Data Structures • Writing to a Text File • Writing to a Binary File • When to Use a Binary File • When to Use a Text File
Example Data Structures #define PNUM 50 /* number of planets */ #define NAMELEN 20struct planet { char name[NAMELEN]; /* known size */ double diameter; double dist_sun;};struct planet earth;struct planet planets[PNUM];/* initialise earth and planets */
Writing to a Text File • Assume a text file is being accessed by the file pointer tp: fprintf(tp, "%s %lf %lf", earth.name, earth.diameter, earth.dist_sun); for (i = 0; i < PNUM; ++i) fprintf(tp, "%s %lf %lf", planets[i].name, planets[i].diameter, planets[i].dist_sun);
Writing to a Binary File • Assume a binary file is being accessed by the file pointer bp: fwrite(&earth, sizeof(planet), 1, bp); fwrite(planets, sizeof(planet)*PNUM, PNUM, bp);
When to Use a Binary File • If the file will contain complicated data structures. • If the file is to be manipulated using byte size-related functions (fwrite(),fseek(),etc).
If speed of access is important(use fseek() instead of a sequential search). • If storage space is important (the data structure size can be defined).
When to Use a Text File • If the file will contain text. • If the file is to be moved between systems (text is portable).