1 / 45

Advanced UNIX

Advanced UNIX. 240-491 Special Topics in Comp. Eng. 1 Semester 2, 2000-2001. Objectives of these slides: a more detailed look at file processing in C. 10. File Processing. Overview. 1. Background 2. Text Files 3. Error Handling 4. Binary Files 5. Direct Access. continued.

keziah
Download Presentation

Advanced UNIX

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Advanced UNIX 240-491 Special Topics in Comp. Eng. 1Semester 2, 2000-2001 • Objectives of these slides: • a more detailed look at file processing in C 10. File Processing

  2. Overview 1. Background 2. Text Files 3. Error Handling 4. Binary Files 5. Direct Access continued

  3. 6. Temporary Files 7. Renaming & Removing 8. Character Pushback 9. Buffering 10. Redirecting I/O

  4. 1. Background • Two types of file: text, binary • Two access methods: sequential, direct(also called random access) • UNIX I/O is line buffered • input is processed a line at a time • output may not be written to a file immediately until a newline is output

  5. 2. Text Files • Standard I/O File I/Oprintf() fprintf()scanf() fscanf()gets() fgets()puts() fputs()getchar() getc()putchar putc() most just add a 'f'

  6. Function Prototypes • int fscanf(FILE *fp, char *format, ...); • int fprintf(FILE *fp, char *format, ...); • int fgets(char *str, int max, FILE *fp); • int fputs(char *str, FILE *fp); • int getc(FILE *fp); • int putc(int ch, FILE *fp); the new argument is the file pointer fp

  7. 2.1. Standard FILE* Constants • Name Meaningstdin standard inputstdout standard outputstderr standard error • e.g.if (len >= MAX_LEN)fprintf(stderr, “String is too long\n”);

  8. 2.2. Opening / Closing • FILE *fopen(char *filename, char *mode); • int fclose(FILE *fp); • fopen() modes:Mode Meaning“r” read mode“w” write mode“a” append mode

  9. Careful Opening • FILE *fp; /* file pointer */char *fname = “myfile.dat”;if ((fp = fopen(fname, “r”)) == NULL) { fprintf(stderr, “Error opening %s\n”, fname); exit(1);}... /* file opened okay */

  10. 2.3. Text I/O • As with standard I/O: • formatted I/O (fprintf, fscanf) • line I/O (fgets, fputs) • character I/O (getc, putc)

  11. 2.3.1. Formatted I/O • int fscanf(FILE *fp, char *format, ...); • int fprintf(FILE *fp, char *format, ...); • Both return EOF if an error or end-of-file occurs. • If okay, fscanf() returns the number of bound variables, fprintf() returns the number of output characters.

  12. 2.3.2. Line I/O • char *fgets(char *str, int max, FILE *fp); • int fputs(char *str, FILE *fp); • If an error or EOF occurs, fgets() returns NULL, fputs() returns EOF. • If okay, fgets() returns pointer to string, fputs() returns non-negative integer.

  13. Differences between fgets() and gets() • Use of max argument: fgets() reads in at most max-1 chars (so there is room for ‘\0’). • fgets() retains the input ‘\n’ • Deleting the ‘\n’: len1 = strlen(line)-1;if (line[len1] == ‘\n’) /* to be safe */ line[len1] = ‘\0’;

  14. Difference between fputs() and puts() • fputs() does not add a‘\n’ to the output.

  15. Line-by-line Echo #define MAX 100 /* max line length */ :void output_file(char *fname){FILE *fp; char line[MAX]; if ((fp = fopen(fname, “r”)) == NULL) { fprintf(stderr, “Error opening %s\n”, fname); exit(1); } while (fgets(line, MAX, fp) != NULL)fputs(line, stdout);fclose(fp);}

  16. 2.3.3. Character I/O • int getc(FILE *fp); • int putc(int ch, FILE *fp); • Both return EOF if an error or end-of-file occurs. • Can also use fgetc() and fputc().

  17. Char-by-char Echo #define MAX 100 /* max line length */ :void output_file(char *fname){ FILE *fp; int ch; if ((fp = fopen(fname, “r”)) == NULL) { fprintf(stderr, “Error opening %s\n”, fname); exit(1); } while ((ch = getc(fp)) != EOF) putc(ch, stdout); fclose(fp);}

  18. Using feof() • Rewrite the previous while-loop as: while (!feof(fp)) { ch = getc(fp); putc(ch, stdout);} • not a common coding style.

  19. 3. Error Handling • int ferror(FILE *fp); • check error status of file stream • it returns non-zero if there is an error • void clearerr(FILE *fp); • reset error status continued

  20. common in advanced coding • void perror(char *str); • print str (usually a filename) followed by colon and a system-defined error message • ...fp = fopen(fname, “r”);if (fp == NULL) {perror(fname); exit(1);}

  21. errno • The system error message is based on a system error number (errno) which is set when a library function returns an error. • #include <errno.h>...fp = fopen(fname, “r”);if (errno == ...) ... continued

  22. Many errno integer constants are defined in errno.h • it is better style to use the constant name instead of the number • linux distributions usually put most errno constants in asm/errno.h • Example errno constants:EPERM permission deniedENOENT no such file / directory

  23. 4. Binary Files • For storing non-character data • arrays, structs, integers (as bytes), GIFs, compressed data • Not portable across different systems • unless you have cross-platform reading/writing utilities, such as gzip • For portability, use text files

  24. fopen() modes for Binary Files • Mode Meaning“rb” read binary file“wb” write binary file“ab” append to binary file add a "b" to the text file modes

  25. Reading / Writing • int fread(void *buffer, int size, int num, FILE *fp);int fwrite(void *buffer, int size, int num, FILE *fp); • Returns number of things read/written (or EOF).

  26. Example • The code will write to a binary file containing employee records with the following type structure: #define MAX_NAME_LEN 50struct employee { int salary; char name[MAX_NAME_LEN + 1];}; continued

  27. struct employee e1, emps[MAX]; : :/* write the struct to fp */fwrite(&e1, sizeof(struct employee), 1, fp);/* write all of the array with 1 op */fwrite(emps, sizeof(struct employee), MAX, fp);

  28. 5. Direct Access • Direct access: move to any record in the binary file and then read (you do not have to read the others before it). • e.g. a move to the 5th employee record would mean a move of size: 4 * sizeof(struct employee) 5th

  29. fopen() Modes for Direct Access (+) • Mode Meaning“rb+” open binary file for read/write“wb+” create/clear binary file for read/write“ab+” open/create binary file for read/write at the end

  30. Employees Example #include <stdio.h>#include <stdlib.h>#include <string.h>#define DF “employees.dat”#define MAX_NAME_LEN 50struct employee { int salary; char name[MAX_NAME_LEN + 1];};int num_emps = 0; /* num of employees in DF */FILE *fp; : Poor style: global variables

  31. e1 e2 e3 e4 Data Format empty space of the right size employees.dat • The basic coding technique is to store the number of employee currently in the file (e.g. 4) • some functions will need this number in order to know where the end of the data occurs . . . . . . . . number

  32. Open the Data File void open_file(void){ if ((fp = fopen(DF, “rb+”)) == NULL) { fp = fopen(DF, “wb+”); /* create file */ num_emps = 0; /* initial num. */ } else /* opened file, read in num. */ fread(&num_emps, sizeof(num_emps), 1, fp);}

  33. Move with fseek() • int fseek(FILE *fp, long offset, int origin); • Movement is specified with a starting position and offset from there. • The current position in the file is indicated with the file position pointer (not the same as fp).

  34. Origin and Offset • fseek() origin values: Name Value MeaningSEEK_SET 0 beginning of fileSEEK_CUR 1 current positionSEEK_END 2 end of file • Offset is a large integer • can be negative (i.e. move backwards) • equals the number of bytes to move

  35. Employees Continued Can write anywhere void put_rec(int posn, struct employee *ep)/* write an employee at position posn */{ long loc; loc = sizeof(num_emps) + ((posn-1)*sizeof(struct employee)); fseek(fp, loc, SEEK_SET);fwrite(ep, sizeof(struct employee), 1,fp);} No checking to avoid over-writing.

  36. Read in an Employee void get_rec(int posn, struct employee *ep)/* read in employee at position posn */{ long loc; loc = sizeof(num_emps) + ((posn-1)*sizeof(struct employee)); fseek(fp, loc, SEEK_SET);fread(ep, sizeof(struct employee), 1,fp);} should really check if ep contains something

  37. Close Employees File void close_file(void){ rewind(fp); /* same as fseek(fp, 0, 0); */ /* update num. of employees */ fwrite(&num_emps, sizeof(num_emps), 1, fp); fclose(fp);}

  38. ftell() • Return current position of the file position pointer (i.e. its offset in bytes from the start of the file): long ftell(FILE *fp);

  39. 6. Temporary Files • FILE *tmpfile(void); /* create a temp file */char *tmpnam(char *name); /* create a unique name */ • tmpfile() opens file with “wb+” mode;removed when program exits

  40. 7. Renaming & Removing • int rename(char *old_name, char *new_name); • like mv in UNIX • int remove(char *filename); • like rm in UNIX

  41. 8. Character Pushback • int ungetc(int ch, FILE *fp); • Overcomes some problems with reading too much • 1 character lookahead can be coded • ungetc() only works once between getc() calls • Cannot pushback EOF

  42. 9. Buffering • int fflush(FILE *fp); • e.g. fflush(stdout); • Flush partial lines • overcomes output line buffering • stderr is not buffered.

  43. setbuf() • void setbuf(FILE *fp, char *buffer); • Most common use is to switch off buffering: setbuf(stdout, NULL); • equivalent to fflush() after every output function call

  44. 10. Redirecting I/O • FILE *freopen(char *filename, char *mode, FILE *fp); • opens the file with the mode and associates the stream with it • Most common use is to redirect stdin, stdout, stderr to mean the file • It is better style (usually) to use I/O redirection at the UNIX level. continued

  45. FILE *in;int n;in = freopen("infile", "r", stdin);if (in == NULL) { perror("infile"); exit(1);}scanf("%d", &n); /* read from infile */ :fclose(in);

More Related