Fundamentals of Programming Lecture 10 Hamed Rasifard 1
Outline File Input/Output 2
Streams and Files The C I/O system supplies a consistent interface to the programmer independent of the actual device being accessed. That is, the C I/O system provides a level of abstraction between the programmer and the device. This abstraction is called a stream, and the actual device is called a file. 3
Streams The C file system is designed to work with a wide variety of devices, including terminals, disk drives, and tape drives. Even though each device is very different, the buffered file system transforms each into a logical device called a stream. Because streams are largely device independent, the same function that can write to a disk file can also write to another type of device, such as the console. There are two types of streams: text and binary. 4
Text Streams A text stream is a sequence of characters. Standard C states that a text stream is organized into lines terminated by a newline character. The newline character is optional on the last line. text stream, certain character translations may occur as required by the host environment. 5
Binary Streams A binary stream is a sequence of bytes that has a one-to-one correspondence to the bytes in the external device that is, no character translations occur. The number of bytes written (or read) is the same as the number on the external device. 6
Files In C, a file may be anything from a disk file to a terminal or printer. A stream could be associated with a specific file by performing an open operation. Once a file is open, information can be exchanged between it and your program. 7
File System Basics The header <stdio.h> provides the prototypes for the I/O functions and defines these three types: size_t, fpos_t, and FILE. The size_t type is some variety of unsigned integer, as is fpos_t. Also defined in <stdio.h> are several macros: NULL, EOF, FOPEN_MAX, SEEK_SET, SEEK_CUR, and SEEK_END. 8
The File Pointer A file pointer is a pointer to a structure of type FILE. It points to information that defines various things about the file, including its name, status, and the current position of the file. In order to read or write files, your program needs to use file pointers. The file pointer declaration: FILE *fp; 9
Opening a File The fopen( ) function opens a stream for use and links a file with that stream. Then it returns the file pointer associated with that file. fopen( ) function prototype: FILE *fopen(const char *filename, const char *mode); 10
Values for Mode Mode r 11 Meaning Open a text file for reading w Create a text file for writing a Append to a text file rb Open a binary file for reading wb Create a binary file for writing ab Append to a binary file r+ Open a text file for read/write w+ Create a text file for read/write a+ Append or create a text file for read/ r+b write Open a binary file for read/write w+b Create a binary file for read/write a+b Append or create a binary file for read/ write
Closing a File The fclose( ) function closes a stream that was opened by a call to fopen( ). It writes any data still remaining in the disk buffer to the file and does a formal operating-systemlevel close on the file. Failure to close a stream invites all kinds of trouble, including lost data, destroyed files, and possible intermittent errors in your program. fclose( ) function prototype: 12 int fclose(file *fp);
Writing a Character The C I/O system defines two equivalent functions that output a character: putc( ) and fputc( ). The putc( ) function writes characters to a file that was previously opened for writing using the fopen( ) function. putc() prototype: int putc(int ch, FILE *fp); 13
Reading a Character There are also two equivalent functions that input a character: getc( ) and fgetc( ). The getc( ) function reads characters from a file opened in read mode by fopen( ). gutc() prototype: int gutc(file *fp); 14
A Simple Disk Program #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { FILE *fp; char ch; if(argc!=2) { printf(''you forgot to enter the filename.\n"); exit(1); if((fp=fopen(argv[1], "w"))==null) { printf(''cannot open file.\n"); exit (1); do { ch = getchar(); putc(ch, fp); while (ch!= '$'); fclose(fp); return 0; 15
Reading Files and Displays Them #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { FILE *fp; char ch; if(argc!=2) { printf("you forgot to enter the filename.\n"); exit(1); if((fp=fopen(argv[1], "r"))==null) { printf("cannot open file.\n"); exit(1); ch = getc(fp); /* read one character */ while (ch!=eof) { putchar(ch); /* print on screen */ ch = getc(fp); fclose(fp); return 0; 16
feof( ) Function getc( ) returns EOF when the end of the file has been encountered. Testing the value returned by getc( ) may not be the best way to determine when you have arrived at the end of a file. C includes the function feof( ), which determines when the end of the file has been encountered feof( ) function prototype: int feof(file *fp); 17
Copy a File #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { FILE *in, *out; char ch; if(argc!=3) printf(''you forgot to enter a filename.\n"); exit(1); if((in=fopen(argv[1], "rb"))==null) { printf("cannot open source file.\n"); exit(1); if((out=fopen(argv[2], "wb")) == NULL) { printf("cannot open destination file.\n"); exit(1); /* This code actually copies the file. */ while(!feof(in)) { ch = getc(in); if(!feof(in)) putc(ch, out); fclose(in); fclose(out); return 0; 18
rewind( ) Functions The rewind( ) function resets the file position indicator to the beginning of the file specified as its argument. feof( ) function prototype: void rewind(file *fp); 19
Going to Beginning of a File #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char str[80]; FILE *fp; if((fp = fopen("test", "w+"))==null) { printf("cannot open file.\n"); exit(1); do { printf("enter a string (CR to quit):\n"); gets(str); strcat(str, "\n"); /* add a newline */ fputs(str, fp); while(*str!='\n'); /* now, read and display the file */ rewind(fp); /* reset file position indicator to start of the file. */ while(!feof(fp)) { fgets(str, 79, fp); printf("%s", str); return 0; 20
fflush() Function If you wish to flush the contents of an output stream, use the fflush( ) function. This function writes the contents of any buffered data to the file associated with fp. If you call fflush ( ) with fp being null, all files opened for output are flushed. fflush() function prototype: 21 int fflush(file *fp);
fread( ) and fwrite( ) Functions To read and write data types that are longer than 1 byte, the C file system provides two functions: fread( ) and fwrite( ). These functions allow the reading and writing of blocks of any type of data. One of the most useful applications of fread( ) and fwrite( ) involves reading and writing user- defined data types, especially structures. fread( ) and fwrite( ) functions prototype: size_t fread(void *buffer, size_t num_bytes, size_t count, FILE *fp); size_t fwrite(const void *buffer, size_t num_bytes, size_t count, FILE *fp); 22
A Simple Mailing list #include <stdio.h> #include <stdlib.h> #define MAX 100 struct addr { char name[30]; char street[40]; char city[20]; char state[3]; unsigned long int zip; addr_list[max]; void init_list (void), enter(void); void delete(void), list(void); void load(void), save(void); int menu_select(void), find_free(void); 23
A Simple Mailing list(cont.) int main(void) { char choice; init_list(); /* initialize the structure array */ for(;;) { choice = menu_select(); switch(choice) { case 1: enter(); break; case 2: delete(); break; case 3: list(); break; case 4: save(); break; case 5: load(); break; case 6: exit(0); return 0; 24
A Simple Mailing list(cont.) /* Initialize the list. */ void init_list(void) { register int t; for(t = 0; t < MAX; ++t) addr_list[t].name[0] = '\0'; /* Get a menu selection. */ int menu_select(void) { char s[80]; int c; printf("1. Enter a name\n"); printf(''2. Delete a name\n"); printf("3. List the file\n"); printf(''4. Save the file\n"); printf("5. Load the file\n"); printf(''6. Quit\n"); do { printf("\nenter your choice: "); gets(s); c = atoi(s); while(c < 0 c > 6); return c; 25
A Simple Mailing list(cont.) /* Input addresses into the list. */ void enter(void) { int slot; char s[80]; slot = find_free(); if(s1ot == -1) { printf("\nlist Full"); return; printf("enter name: "); gets(addr_list[slot].name); printf("enter street: "); gets(addr_list[slot].street); printf("enter city: "); gets(addr_list[slot].city); printf("enter state: "); gets(addr_list[slot].state); printf("enter zip: "); gets(s); addr_list[slot].zip = strtoul(s, '\0', 10); 26
A Simple Mailing list(cont.) /* Find an unused structure. */ int find_free(void) { register int t; for(t=0; addr_list[t].name[0] && t<max; ++t) ; if(t==max) return -1; /* no slots free */ return t; /* Delete an address. */ void delete(void) { register int slot; char s[80]; printf("enter record #: "); gets(s); slot = atoi(s); if(s1ot>=0 && slot < MAX) addr_list[slot].name [0] = '\0'; 27
A Simple Mailing list(cont.) /* Display the list on the screen. */ void list (void) { register int t; for(t=0; t<max; ++t) { if(addr_list[t].name[0]) { printf(''%s\n", addr_list[t].name); printf("%s\n", addr_list[t].street); printf("%s\n", addr_list[t].city); printf("%s\n", addr_list[t].state); printf("%lu\n\n", addr_list[t].zip); printf("\n\n"); 28
A Simple Mailing list(cont.) /* Save the list. */ void save(void) { FILE *fp; register int i; if((fp=fopen("maillist", "wb"))==null) { printf(''cannot open file.\n"); return; for(i=0; i<max; i++) if(*addr_list[i].name) if(fwrite(&addr_list[i], sizeof(struct addr), 1, fp)!=1) printf("file write error.\n"); fclose(fp); 29
A Simple Mailing list(cont.) /* Load the file. */ void load(void) { FILE *fp; register int i; if((fp=fopen("maillist", "rb"))==null) { printf(''cannot open file.\n"); return; init_list(); for(i=0; i<max; i++) if(fread(&addr_list[i], sizeof(struct addr), 1, fp)!=l) { if(feof(fp)) break; printf("file read error.\n"); fclose(fp); 30