c_week11 | Filename | Pointer (Computer Programming)

Lecture 11, Page 1

BIL 104E

INTRODUCTION TO
SCIENTIFIC AND ENGINEERING

COMPUTING

Compiled by Ergin TARI

Lecture 11, Page 2

INFORMATION TO USERS
THE NOTES IN THE FOLLOWING SLIDES ARE COMPILED FROM FREE VERSIONS OF THE BOOKS Sams Teach Yourself C in 21 Days (Sams Teach Yourself) By Peter Aitken and Sams Teach Yourself C in 24 Hours (Published by Sams) By Tony Zhang.
The electronic versions of these and other books can be found in the web pages including

http://server11.hypermart.net/davidbook901/data/c/c1f8c0d9.htm http://www.informit.com/itlibrary http://www.free-book.co.uk/computers-internet/programming/c/ http://aelinik.free.fr/c/

Compiled by Ergin TARI

Lecture 11, Page 3

BIL104E: Introduction to Scientific and Engineering Computing, Summer 2007 Lecture 11
Outline Introduction Files and streams Opening a file with fopen() Closing a file with fclose() The feof() function ….. The fgetc() and fputc() functions The fgets() and fputs() functions The fread() and fwrite() functions Summary
Compiled by Ergin TARI

Lecture 11, Page 4

Introduction

• Data files
– Can be created, updated, and processed by C
programs – Are used for permanent storage of large amounts of

data
• Storage of data in variables and arrays is only temporary

Compiled by Ergin TARI

Lecture 11, Page 5

The Data Hierarchy

• Data Hierarchy:
– Bit – smallest data item
• Value of 0 or 1

– Byte – 8 bits
• Used to store a character – Decimal digits, letters, and special symbols

– Field – group of characters conveying meaning
• Example: your name

– Record – group of related fields
• Represented by a struct

• Example: In a payroll system, a record for a particular employee that contained his/her identification number, name, address, etc.
Compiled by Ergin TARI

Page 6 The Data Hierarchy • Data Hierarchy (continued): – File – group of related records • Example: payroll file – Database – group of related files Sally Tom Judy Iris Randy Black Blue Green Orange Red File Judy Judy Green Field (ASCII character J) Record 01001010 Byte 1 Bit Compiled by Ergin TARI .Lecture 11.

"Reading from and Writing to Standard I/O.Lecture 11. Page 7 Disk Files • In former weeks. Compiled by Ergin TARI . In this lesson you'll learn to read data from or write data to disk files." you learned how to read or write characters through standard input or output.

or a tape drive. To perform I/O operations. or from one machine to another. which is a series of bytes. or vice versa. Not like a file. Page 8 Files Versus Streams • What Is a File? In C. a file can refer to a disk file. which is required to keep the exact contents of the file. a stream is deviceindependent. In other words. is called a stream. The second format of streams is called the binary stream. Compiled by Ergin TARI . ASCII data). There are two formats of streams. which consists of a sequence of characters (that is.Lecture 11. you can read from or write to any type of files by simply associating a stream to the file. which has a consistent appearance from one environment to another. Text streams are used for textual data. which is a series of bytes. All streams have the same behavior. Binary streams are primarily used for nontextual data. • What Is a Stream? The data flow you transfer from your program to a file. Depending on the compilers. a terminal. each character line in a text stream may be terminated by a newline character. The content of an .exe file would be one example. a file represents a concrete device with which you want to exchange information. The first one is called the text stream. a printer.

Page 9 – File ends with the end-of-file marker(EOF) • Or.standard error (screen) Compiled by Ergin TARI .standard output (screen) • stderr .Files and Streams • C views each file as a sequence of bytes Lecture 11.standard input (keyboard) • stdout . file ends at a specified byte • Stream created when a file is opened – Provide communication channel between files and programs – Opening a file returns a pointer to a FILE structure Example file pointers: • stdin .

The NULL and end-of-line characters have no special significance and are treated like any other byte of data. Any and all data is written and read unchanged. each CR-LF is translated to a \n. each \n is translated to a CR-LF. whereas other functions can use either mode. It's important to remember that a "line" isn't a C string. On DOS systems. Compiled by Ergin TARI . Binary streams are associated with binary-mode files. when data is read from a disk file. and it's important that you understand the distinction in order to use the proper mode for your files. You can associate either type of stream with a file. Text streams are associated with text-mode files. When you use a text-mode stream. Each line contains zero or more characters and ends with one or more characters that signal end-of-line. Page 10 Types of Disk Files C streams come in two kinds: text and binary. On UNIX systems. it's a carriage-return linefeed (CR-LF) combination. there is no terminating NULL character (\0). When data is written to a text-mode file. translation occurs between C's newline character (\n) and whatever character(s) the operating system uses to mark end-of-line on disk files.Lecture 11. Text-mode files consist of a sequence of lines. no translation is done--newline characters remain unchanged. The maximum line length is 255 characters. Some file input/output functions are restricted to one file mode. with no separation into lines and no use of end-of-line characters.

x.Lecture 11. The rules as to what is acceptable for filenames and what is not differ from one operating system to another. the following characters are not permitted: /\:*?"<>| You must be aware of the filename rules of whichever operating system you're writing for. just like other text data. Operating systems also differ in the characters that are permitted in filenames. Filenames are stored as strings. In Windows 95. as well as most UNIX systems. permit filenames up to 256 characters long. for example. In DOS and Windows 3. and you must use filenames when dealing with disk files. the Windows 95 and Windows NT operating systems. Compiled by Ergin TARI . In contrast. a complete filename consists of a name that has from one to eight characters. Page 11 Filenames Every disk file has a name. optionally followed by a period and an extension that has from one to three characters.

it will be assumed that the file is located at whatever location the operating system currently designates as the default. the backslash character is used to separate directory names in a path. On PCs. For example. If you specify a filename without a path. The path specifies the drive and/or directory (or folder) where the file is located. however. To represent the backslash character itself. Page 12 Filenames A filename in a C program also can contain path information. to DOS and Windows. Compiled by Ergin TARI . the name You are strictly required to do if use windows z:\data\list. For example.TXT in the directory \DATA on drive Z. Thus. Remember that the backslash character has a special meaning to C when it's in a string. enter only a single backslash.txt". If you're entering a filename using the keyboard. you must precede it with another backslash. you would represent the filename as follows: char *filename = ”z:\\data\\list. in a C program.Lecture 11.txt refers to a file named LIST. Not all systems use the backslash as the directory separator. UNIX uses the forward slash (/). It's good programming practice to always specify path information as part of your filenames.

called the file position indicator. that points to the position in a file where data will be read from or written to. A file pointer is used by a stream to conduct the operation of the I/O functions. For instance.h. A pointer of type FILE is called a file pointer. Page 13 The Basics of Disk File I/O Pointers of FILE The FILE structure is the file control structure defined in the header file stdio.Lecture 11. In the FILE structure there is a member. the following defines a file pointer called fptr: FILE *fptr. Compiled by Ergin TARI . which references a disk file.

Lecture 11. The filename is given to the file that is about to be opened by the fopen() function. Here filename is a char pointer that references a string of a filename. the fopen() function returns a null pointer. mode points to another string that specifies the way to open the file. const char *mode). Compiled by Ergin TARI .h> FILE *fopen(const char *filename. Page 14 Opening a File with fopen() function The syntax for the fopen() function is #include <stdio. If an error occurs during the procedure to open a file. The fopen() function returns a pointer of type FILE.

Similarly. Compiled by Ergin TARI .Lecture 11. Note that you might see people use the mode "rb+" instead of "r+b". – "w+" creates a text file for reading or writing. – "a+" opens or creates a text file for appending. These two strings are equivalent. – "wb" creates a binary file for writing. "ab+" is equivalent to "a+b". – "w" creates a text file for writing. – "a" opens an existing text file for appending. – "r+b" opens an existing binary file for reading or writing. "wb+" is the same as "w+b". – "w+b" creates a binary file for reading or writing. Page 15 Opening a File with fopen() function The following list shows the possible ways to open a file by various strings of modes: – "r" opens an existing text file for reading. – "r+" opens an existing text file for reading or writing. – "a+b" opens or creates a binary file for appending. – "ab" opens an existing binary file for appending. – "rb" opens an existing binary file for reading.

If an error occurs when the fopen() function tries to open the file.txt". if ( (fptr = fopen("test. Page 16 Example: Opening a File with fopen() function • The following statements try to open a file called test.\n"). "r")) == NULL){ printf("Cannot open test.Lecture 11. the function returns a null pointer. Compiled by Ergin TARI .txt file. } Here "r" is used to indicate that a text file is about to be opened for reading only. exit(1).txt: FILE *fptr. Then an error message is printed out by the printf() function and the program is aborted by calling the exit() function with a nonzero value.

written. Page 17 Closing a File with fclose() function After a disk file is read. Normally. Compiled by Ergin TARI . the fclose() function fails only when the disk is removed before the function is called or there is no more space left on the disk. Here stream is a file pointer that is associated with a stream to the opened file. The syntax for the fclose() function is #include <stdio. the function returns EOF. you have to disassociate the file from a specified stream by calling the fclose() function. or appended with some new data.h> int fclose(FILE *stream). it returns 0.Lecture 11. If fclose() closes a file successfully. Otherwise.

18: fclose(fptr). 22: } Output The value of fptr: 0x013E Ready to close the file."). FAIL}. 15: } else { 16: printf("The value of fptr: 0x%p\n". "r")) == NULL){ 13: printf("Cannot open %s. 11: 12: if ((fptr = fopen(filename. 5: 6: main(void) 7: { 8: FILE *fptr.\n". 14: reval = FAIL. Page 18 Example: opening and closing a text file 1: /* Opening and closing a file */ 2: #include <stdio.txt". 9: char filename[]= "haiku. 19: } 20: 21: return reval. 17: printf("Ready to close the file.Lecture 11. Compiled by Ergin TARI . 10: int reval = SUCCESS.h> 4: enum {SUCCESS. filename). fptr).

• If. Line 13 then prints a warning message. • If an error occurs when you try to open the text file. however. Page 19 ANALYSIS • From the expression in line 12. • From the output shown on my screen. the return statement returns the value of reval that contains 0 if the text file has been opened successfully. we know that the value of FAIL is 1. and line 18 then closes the file by calling the fclose() file. the fopen() function opens the text file successfully. or 1 otherwise. Compiled by Ergin TARI .Lecture 11. you can see that the fopen() function tries to open a text file with the name contained by the character array filename for reading.txt in line 9. I see that the value held by the file pointer fptr is 0x013E after the text file is opened. and line 14 assigns the value represented by the enum name FAIL to the int variable reval. the fopen() function returns a null pointer. The filename array is defined and initialized with the name haiku. • In line 21. From the declaration of the enum data type in line 4. Line 17 tells the user that the program is about to close the file. the statement in line 16 prints the value contained by the file pointer fptr.

At other times. you don't know how long the file is. starting at the beginning and proceeding to the end. if you used fwrite() to save a 100-element integer array. The symbolic constant EOF is defined in STDIO. When a character input function reads EOF from a text-mode stream. For example. however. When reading from a text-mode file character-by-character.and text-mode files: int feof(FILE *fp). so there's no need to be able to detect the file's end. a value never used by a "real" character. you can be sure that you've reached the end of the file. For example. Instead. There are two ways to detect end-of-file. which can be used for both binary. you could write the following: while ( (c = fgetc( fp )) != EOF ) With a binary-mode stream. which would result in premature end of input.Lecture 11. Page 20 Detecting the End of a File Sometimes you know exactly how long a file is. Compiled by Ergin TARI . The function feof() returns 0 if the end of file fp hasn't been reached. you can't detect the end-of-file by looking for -1. you can look for the end-of-file character. you can use the library function feof(). The argument fp is the FILE pointer returned by fopen() when the file was opened.H as -1. because a byte of data from a binary stream could have that value. you know the file is 200 bytes long (assuming 2-byte integers). or a nonzero value if end-of-file has been reached. but you still want to read data from the file.

This function is more useful when you're reading a binary file because the values of some bytes may be equal to the value of EOF. it returns a nonzero integer. a function called feof() can be used to determine when the end of a file is encountered.h> int feof(FILE *stream). otherwise. Page 21 feof() function In C. you may end up at the wrong position. Here stream is the file pointer that is associated with an opened file. Using the feof() function helps you to avoid mistakes in determining the end of a file. Compiled by Ergin TARI . The feof() function returns 0 if the end of the file has not been reached.Lecture 11. If you determine the end of a binary file by checking the value returned by fread(). The syntax for the feof() function is #include <stdio.

} puts("Enter name of text file to display: "). FILE *fp.h> #include <stdio. printf("%s". } /* If end of file not reached.").buf). } Compiled by Ergin TARI . read a line and display it. world. /* Open the file for reading.c #include <stdio.h> #define BUFSIZE 100 main() { char buf[BUFSIZE]. */ if ( (fp = fopen(filename. BUFSIZE. return(0). char filename[60]."). Page 22 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: 33: /* Detecting end-of-file. exit(1). return(0). gets(filename). */ #include <stdlib. "r")) == NULL) { fprintf(stderr.h> main() { printf("Hello. fp). "Error opening file.Lecture 11. Enter name of text file to display: hello. */ while ( !feof(fp) ) { fgets(buf. } fclose(fp).

you pass the pointer that was returned when you opened the file with fopen(). Page 23 Formatted File Output Formatted file output is done with the library function fprintf().. The first argument is a pointer to type FILE. Remember. if you specify a stream argument of stdout. This is just like printf(). The format string used by fprintf() follows exactly the same rules as printf(). The second argument is the format string. fprintf() takes zero. In fact.. char *fmt. . fprintf() is identical to printf(). In other words. These arguments are the names of the variables to be output to the specified stream.H. Compiled by Ergin TARI . To write data to a particular disk file. except that it sends its output to the stream specified in the argument list. and it reads as follows: int fprintf(FILE *fp. one. or more additional arguments.). in addition to the file pointer and the format string arguments. ellipses represent a variable number of arguments.Lecture 11. The prototype of fprintf() is in the header file STDIO. In a function prototype. fprintf() works just like printf(). You learned about format strings in the discussion of printf().

1000. 30: exit(1). 11: int count.0001 12: char filename[20]. 13: Enter a name for the file. &data[count]). Page 24 1: /* Demonstrates the fprintf() function. count++) 17: scanf("%f". 14: puts("Enter 5 floating-point numerical values.". 26: 27: if ( (fp = fopen(filename. 6: 3."). 3. 31: } 32: 33: values.99 8: { 9: FILE *fp. count < 5. 25: gets(filename). "w")) == NULL) 28: { 29: fprintf(stderr. Compiled by Ergin TARI . 1. 18: 19: /* Get the filename and open the file.Lecture 11. numbers. */ 21: 22: clear_kb(). */ 2: #include <stdlib. "Error opening file %s. First clear stdin */ 20: /* of any extra characters.txt 15: 16: for (count = 0.50 10: float data[5].14159 7: main() 9. 23: 24: puts("Enter a name for the file. filename).").h> 4: Enter 5 floating-point numerical 5: void clear_kb(void).h> 3: #include <stdio.

numbers. 3.990000 data[2] = 1. 41: printf("\n"). data[count]). count < 5.50 48: char junk[80]. 38: fprintf(stdout. 44: 3.500000 data[3] = 3.txt data[0] = 3. 1000. count. count++) 36: { 37: fprintf(fp. "\ndata[%d] = %f". */ 34: 35: for (count = 0.000122 Compiled by Ergin TARI . 42: return(0). count.99 47: { 1.0001 50: } Enter a name for the file. 39: } 40: fclose(fp).000000 data[4] = 1000.14159 45: void clear_kb(void) 46: /* Clears stdin of any waiting characters. 49: gets(junk). data[count]).Lecture 11. "\ndata[%d] = %f". Page 25 /* Write the numerical data to the file and to stdout. */ 9.141590 data[1] = 9. 43: } Enter 5 floating-point numerical values.

The components of the format string are the same as for scanf().Lecture 11.TXT. use the fscanf() library function.00456 1.).02 0. and enter five floating-point numbers with some space between them (spaces or newlines). Use your editor to create a file named INPUT. Page 26 Formatted File Input For formatted file input.) indicate one or more additional arguments.001 100. the addresses of the variables where fscanf() is to assign the input. except that input comes from a specified stream instead of from stdin. For example.. To demonstrate fscanf(). The argument fp is the pointer to type FILE returned by fopen(). except that characters are taken from the specified stream rather than from stdin...0005 Compiled by Ergin TARI . which is used like scanf(). you might want to review the section on scanf(). and fmt is a pointer to the format string that specifies how fscanf() is to read the input. Before getting started with fscanf(). your file might look like this: 123. . const char *fmt. The function fscanf() works exactly the same as scanf(). The prototype for fscanf() is int fscanf(FILE *fp. Finally..45 87. the ellipses (. you need a text file containing some numbers or strings in a format that can be read by the function.

0001. f2. "%f %f %f %f %f". &f5).Lecture 11. and %f\n.02. 100. 123.".001 100. Compiled by Ergin TARI . f1. } fscanf(fp.00456.\n"). return(0). */ #include <stdlib. printf("The values are %f. } The values are 123.45 87. Page 27 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: /* Reading formatted file data with fscanf(). &f4. f5.TXT". f2. f3. exit(1). fclose(fp). FILE *fp. &f2.h> #include <stdio.0005.h> main() { float f1. &f1. %f. "Error opening file. 0. &f3. "r")) == NULL) { fprintf(stderr. f5).02 0. f4. 87. %f.0005 if ( (fp = fopen("INPUT. f3.45. f4. and 1.00456 1. %f.

txt file. haiku. one character line) at a time.txt. Page 28 Reading and Writing Disk Files The program in the previous slides does not do anything with the text file. So how can you read them from the file? In C. except open and close it. Compiled by Ergin TARI . – Read or write one line of text (that is. In fact.Lecture 11. written by Sodo and Chora. saved in the haiku. there are two pieces of Japanese haiku. you can perform I/O operations in the following ways: – Read or write one character at a time. – Read or write one block of characters at a time.

The syntax for the fputc() function is #include <stdio. the fputc() function advances the associated file pointer. The function then returns the value of an int that is converted from the character. FILE *stream). stream is the file pointer that is associated with a stream. fputc() functions • The syntax for the fgetc() function is #include <stdio. Here c is an int value that represents a character. it returns EOF. otherwise.Lecture 11. Compiled by Ergin TARI . Page 29 One Character at a Time: fgetc(). the int value is converted to an unsigned char before being outputted. After a character is written. The fgetc() function fetches the next character from the stream specified by stream. The fputc() function returns the character written if the function is successful.h> int fputc(int c .h> int fgetc(FILE *stream). In fact. • Here stream is the file pointer that is associated with a stream.

Lecture 11. 23: fclose(fptr1). FILE *fout).txt". FAIL}. *fptr2. 21: } else { 22: CharReadWrite(fptr2. 14: 15: if ((fptr1 = fopen(filename1.Sodo (1641-1716) A storm wind blows out from among the grasses the full moon grows.txt".\n". --. filename2). 20: reval = FAIL. 5: 6: void CharReadWrite(FILE *fin. "r")) == NULL){ 19: printf("Cannot open %s. "w")) == NULL){ 16: printf("Cannot open %s. 33: 34: while ((c=fgetc(fin)) != EOF){ 35: fputc(c.\n". Page 30 Example:One Character at a Time: fgetc(). /* write to a file */ 36: putchar(c). 12: char filename2[]= "haiku.Chora (1729-1781) Compiled by Ergin TARI Output . /* put the character on the screen */ 37: } 38: } Leading me along my shadow goes back home from looking at the moon. 25: } 27: return reval. 24: fclose(fptr2). filename1). 17: reval = FAIL. fout). 7: 8: main(void) 9: { 10: FILE *fptr1. 11: char filename1[]= "outhaiku. 18: } else if ((fptr2 = fopen(filename2. --. fptr1). 13: int reval = SUCCESS. FILE *fout) 31: { 32: int c.h> 4: enum {SUCCESS. 28: } 29: /* function definition */ 30: void CharReadWrite(FILE *fin. fputc() functions 1: /* Reading and writing one character at a time */ 2: #include <stdio.

(See the declaration of the CharReadWrite() function in line 6. If the file outhaiku. Compiled by Ergin TARI • • • • . haiku. a warning message is printed out in line 16. from the book.txt is the text file that is going to be read by the program.) The statement in line 10 defines two file pointers. the reval variable is assigned 1 and is represented by the enum name FAIL. in line 17. called haiku. a text file with the name outhaiku. In line 15.txt. Lines 11 and 12 define two character arrays. Page 31 Analysis • The purpose of the program is to read one character from a file. and put it in the same directory where you save the executable file.txt. The file pointer fptr1 is associated with the file. which has two file pointers as its arguments.txt is opened for writing. outhaiku. which means an error occurs. fptr1 and fptr2. which are used later in the program.txt is contained by the filename1 array. and initialize the two arrays with two strings containing filenames.txt is opened successfully.Lecture 11. write the character to another file. and then display the character on the screen. The file pointer fptr2 is associated with the opened text file. haiku. If the fopen() function returns NULL.txt and haiku.txt. is opened for reading in line 18. Also. outhaiku. another text file. filename1 and filename2. (You need to copy or create the file.) In the program there is a function called CharReadWrite().

txt file to another text file.txt. In addition. After the CharReadWrite() function finishes its job.txt file contains two pieces of Japanese haiku written by Sodo and Chora. • • • Compiled by Ergin TARI .txt. putchar() is called in line 36 in order to put the character returned by the fgetc() function on the screen. passed to the function as arguments. the two opened files.txt text file until the function reaches the end of the file. which is pointed to by fout. we see the two pieces of haiku shown on the screen. outhaiku. the fputc() function in line 35 writes each character read from the haiku. are closed with a call to the fclose() function respectively in lines 23 and 24.txt has been correctly copied to outhaiku. From the definition of the CharReadWrite() function in lines 30 and 38. Page 32 Analysis • If no error occurs.) Within the while loop.Lecture 11.2 is run successfully. As mentioned earlier.txt file as well. fptr1 and fptr2. If the program in Listing 21. we see that there is a while loop that keeps calling the fgetc() function to read the next character from the haiku. and they are written into the outhaiku. the haiku. the CharReadWrite() function is invoked in line 22 with two file pointers.txt in a text editor to confirm that the content of haiku. which are associated with fptr1 and fptr2. You can view outhaiku. (See line 34.

• Here s references a character array that is used to store characters read from the opened file pointed to by the file pointer stream. and can append a null character after the last character fetched. The syntax for the fgets() function is #include <stdio.Lecture 11. The gets() function just replaces the newline character with a null character. the fgets() function returns the char pointer s. and the contents of the array are unknown. fgets() and fputs(). fputs() functions • You can also read or write one character line at time. the function returns a null pointer. This is different from what the gets() function does. int n. until a newline or an EOF is encountered. Page 33 One Line at a Time: fgets(). If an error occurs. If EOF is encountered. n specifies the maximum number of array elements.h> char *fgets(char *s. The fgets() function can read up to n-1 characters. Compiled by Ergin TARI . If it is successful. There is a pair of C I/O functions. that allows you to do so. FILE *stream). Note that if a newline is encountered during the reading. the fgets() function includes the newline in the array. the fgets() function returns a null pointer and leaves the array untouched.

The const modifier indicates that the content of the array pointed to by s cannot be changed. FILE *stream). Page 34 One Line at a Time: fgets(). The modified version is shown in te next slide. Here s points to the array that contains the characters to be written to a file associated with the file pointer stream. the fputs() function does not insert a newline character to the string written to a file. • Note that the character array must include a null character at the end as the terminator to the fputs() function. Also.h> int fputs(const char *s. fputs() functions • The syntax for the fputs() function is #include <stdio. unlike the puts() function. Compiled by Ergin TARI . We can modify the previous program to read or write one character line at a time by calling the fgets() and fputs() functions. If it fails. it returns zero.Lecture 11. otherwise. the fputs() function returns a nonzero value.

fout). 38: } 12: char filename2[]= "haiku. *fptr2. MAX_LEN.h> 30: void LineReadWrite(FILE *fin.Sodo 18: } else if ((fptr2 = fopen(filename2. 31: { 5: 32: char buff[MAX_LEN]. --. "w")) == NULL){ 16: printf("Cannot open %s for writing.Example: One Line at a Time: fgets(). FILE *fout). Page 35 1: /* Reading and writing one line at a time */ 29: /* function definition */ 2: #include <stdio. 23: fclose(fptr1).\n".\n". 9: { 36: printf("%s". filename1). the full moon grows. 13: int reval = SUCCESS. FAIL. fptr1). FILE *fout) 4: enum {SUCCESS. Leading me along 14: my shadow goes back home 15: if ((fptr1 = fopen(filename1. 6: void LineReadWrite(FILE *fin. --. 17: reval = FAIL. "r")) == NULL){ (1641-1716) 19: printf("Cannot open %s for reading.txt".Chora 25: } (1729-1781) Compiled by Ergin TARI 27: return reval. buff). filename2). 37: } 11: char filename1[]= "outhaiku. 20: reval = FAIL. from looking at the moon.txt". fin) != NULL){ 8: main(void) 35: fputs(buff. 10: FILE *fptr1.} Output . 24: fclose(fptr2). 33: 7: 34: while (fgets(buff. A storm wind blows 21: } else { out from among the grasses 22: LineReadWrite(fptr2. MAX_LEN = 81}. fputs() functions Lecture 11.

The definition of the LineReadWrite() function is shown in lines 30_38. The fgets() function is called repeatedly in a while loop to read one character line at a time from the haiku.txt file in a text editor to make sure that the contents of the haiku. until it reaches the end of the text file.txt file have been copied to the outhaiku. you can see that a function called LineReadWrite() has replaced the CharReadWrite() function.txt that is associated with the file pointer fout. In line 34. each line read by the fgets() function is written to another opened text file called outhaiku. Page 36 Analysis • • From the program. along with the file pointer fin that is associated with the opened haiku.Lecture 11. the array name buff and the maximum number of the array elements MAX_LEN are passed to the fgets() function.txt text file. Compiled by Ergin TARI • • . Also.txt file. you can view the outhaiku. Meanwhile. This is done by invoking the fputs() function in line 35.txt file. The statement in line 36 prints the contents of each string on the screen so that you see the two pieces of Japanese verse after running the program.

Here ptr is a pointer to an array in which the data is stored. Page 37 One Block at a Time: fread(). n specifies the number of elements to read. fwrite() functions • The fread() and fwrite() functions are mirror images of each other. if an error occurs or an EOF is encountered. The syntax for the fread() function is #include <stdio. • The number of elements read by the fread() function should be equal to the value specified by the third argument to the function.Lecture 11.h. size_t is an integral type defined in the header file stdio.h> size_t fread(void *ptr. FILE *stream). size indicates the size of each array element. unless an error occurs or an EOF (endof-file) is encountered. The fread() function returns the number of elements actually read. stream is a file pointer that is associated with the opened file for reading. Compiled by Ergin TARI . size_t size. The fread() function returns the number of elements that are actually read. size_t n.

n specifies the number of elements to be written. Note that it's the programmer's responsibility to ensure that the array is large enough to hold data for either the fread() function or the fwrite() function.h> size_t fwrite(const void *ptr. fwrite() functions • The syntax for the fwrite() function is #include <stdio. size_t size.Lecture 11. size_t n. • Here ptr references the array that contains the data to be written to an opened file pointed to by the file pointer stream. the number returned by fwrite() should be the same as the third argument in the function. If there is no error occurring. The fwrite() function returns the number of elements actually written. size indicates the size of each element in the array. Page 38 One Block at a Time: fread(). The return value may be less than the specified value if an error occurs. Compiled by Ergin TARI • • . FILE *stream).

sizeof(char). sizeof(char). 38: fwrite(buff. 36: buff[num * sizeof(char)] = `\0'. fptr1).txt".txt". FILE *fout) 5: 30: { 6: void BlockReadWrite(FILE *fin. 44: printf("Cannot open %s. MAX_LEN. 45: return FAIL. 29: void BlockReadWrite(FILE *fin. 31: int num.\n". Page 39 Example:One Block at a Time: fread(). 39: } 15: 40: } 16: if ((fptr1 = fopen(filename1. 14: int reval = SUCCESS. 24: } 46: } 26: return reval. FAIL. 32: char buff[MAX_LEN + 1]. str). buff). 27: } Compiled by Ergin TARI . "w")) == NULL){ 17: reval = ErrorMsg(filename1). fout). FILE *fout). 43: { 22: fclose(fptr1). 18: } else if ((fptr2 = fopen(filename2. 37: printf("%s". 7: int ErrorMsg(char *str). 8: 33: 9: main(void) 34: while (!feof(fin)){ 10: { 35: num = fread(buff.Lecture 11. 23: fclose(fptr2). MAX_LEN = 80}.h> 28: /* function definition */ 4: enum {SUCCESS. "r")) == NULL){ 19: reval = ErrorMsg(filename2). fin). 11: FILE *fptr1. 13: char filename2[]= "haiku. 41: /* function definition */ 20: } else { 42: int ErrorMsg(char *str) 21: BlockReadWrite(fptr2. /* append null character */ 12: char filename1[]= "outhaiku. *fptr2. num. fwrite() functions 1: /* Reading and writing one block at a time */ 2: #include <stdio.

*/ 13: 14: for (count = 0. array2[SIZE]. 47: exit(1). 48: } 49: 50: fclose(fp). */ 53: 54: for (count = 0. sizeof(int). count++) 15: array1[count] = 2 * count. count++) 55: printf("%d\t%d\n". "Error reading file.h> 3: #include <stdio. 51: 52: /* Now display both arrays to show they're the same. */ 18: 19: if ( (fp = fopen("direct. "Error opening file. "Error opening file. count < SIZE."). */ 35: 36: if ( (fp = fopen("direct. 40: } 41: 42: /* Read the data into array2[]. 22: exit(1). */ 25: 26: if (fwrite(array1. fp) != SIZE) 27: { 28: fprintf(stderr. 57: } 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 Compiled by Ergin TARI .1: /* Direct file I/O with fwrite() and fread(). array1[count]. SIZE. 23: } 24: /* Save array1[] to the file. fp) != SIZE) 45: { 46: fprintf(stderr. sizeof(int). count < SIZE. SIZE. 29: exit(1). 30: } 32: fclose(fp). "wb")) == NULL) 20: { 21: fprintf(stderr."). 33: Lecture 11. array1[SIZE]. Page 40 34: /* Now open the same file for reading in binary mode. */ 2: #include <stdlib."). 56: return(0). 10: FILE *fp. 39: exit(1). */ 43: 44: if (fread(array2. 11: 12: /* Initialize array1[].txt". array2[count]). "rb")) == NULL) 37: { 38: fprintf(stderr.").txt". 16: 17: /* Open a binary mode file.h> 5: #define SIZE 20 6: 7: main() 8: { 9: int count. "Error writing to file.

txt to another file called outhaiku. Compiled by Ergin TARI • • . We call the two C I/O functions from our own function. In the program. The while loop. the haiku.txt file is read by the fread() function. and then the fwrite() function is used to write the contents read from haiku. which means that the end of the text file has been reached. we use the sizof operator to measure the size of the char data type because the elements in the buff array are all characters. As shown in lines 35 and 38.Lecture 11. BlockReadWrite().txt. you can see that a character array called buff is defined with the number of elements of MAX_LEN + 1 in line 32. Page 41 Analysis • The purpose of the program is to show you how to invoke the fread() and fwrite() functions in your program to perform block I/O operations. shown in lines 34_39. until the feof() function in line 34 returns 0. keeps calling the fread() function to read a character block with MAX_LEN elements. From the definition of the BlockReadWrite() function in lines 29_40. although we only read MAX_LEN number of characters by calling the fread() function in line 35. The reason is that we append a null character in line 36 after the last character read so that we ensure the block of characters saved in buff is treated as a string and can be printed out on the screen properly by the printf() function in line 37.

Lecture 11. Page 42 Beyond the basics Compiled by Ergin TARI .

It's typically on the order of a few hundred to a thousand bytes. the file's buffer is flushed (written to the file). it's a good idea to close streams explicitly--particularly those linked to disk files--as soon as you're finished with them. Compiled by Ergin TARI . When a program terminates (either by reaching the end of main() or by executing the exit() function). The reason has to do with stream buffers. When you create a stream linked to a disk file. The argument fp is the FILE pointer associated with the stream. stdout. Buffers are needed because disk drives are block-oriented devices. Its prototype is int fcloseall(void). depending on the specific hardware in use. and stdaux) by using the fcloseall() function. You don't need to be concerned about the exact block size. you should close it using the fclose() function. You can also close all open streams except the standard ones (stdin. A buffer is a block of memory used for temporary storage of data being written to and read from the file. Its prototype is int fclose(FILE *fp). Page 43 File Buffering: Closing and Flushing Files When you're done using a file. This function also flushes any stream buffers and returns the number of streams closed. however.Lecture 11. a buffer is automatically created and associated with the stream. which means that they operate most efficiently when data is read and written in blocks of a certain size. fclose() returns 0 on success or -1 on error. The size of the ideal block differs. When you close a file. However. stderr. all streams are automatically flushed and closed. stdprn.

this buffer operation means that. The prototypes of these two functions are as follows: int fflush(FILE *fp). The function flushall() returns the number of open streams. to the disk. If the file was opened for reading.Lecture 11. you don't have to be concerned with them. fflush() writes its buffer to disk. Compiled by Ergin TARI . or if some other problem occurs. the data is saved in the buffer until the buffer is full. (C does offer some functions for buffer manipulation) In practical terms. during program execution. as a block. As your program writes data to the stream. Use flushall() to flush the buffers of all open streams. If your program hangs up. The function fflush() returns 0 on success or EOF if an error occurred. the buffer is cleared. Use fflush() when you want a file's buffer to be written to disk while still using the file. If a file was opened for writing. and then the entire contents of the buffer are written. int flushall(void). data that your program wrote to the disk might still be in the buffer. not on the disk. The creation and operation of the buffer are handled by the operating system and are entirely automatic. and you won't know what's contained in the disk file. The argument fp is the FILE pointer returned by fopen() when the file was opened. An analogous process occurs when reading data from a disk file. Page 44 File Buffering: Closing and Flushing Files The buffer associated with a file stream serves as an interface between the stream (which is character-oriented) and the disk hardware (which is block-oriented). You can flush a stream's buffers without closing it by using the fflush() or flushall() library functions. if there's a power failure. the data that's still in the buffer might be lost.

Here.) When an existing file is opened. Writing and reading operations occur at the location of the position indicator and update the position indicator as well. (Because the file is new and has a length of 0. there's no other location to indicate. or write data to. position 0. By controlling the position indicator. and 10 bytes are read. For example. random means that you can read data from. because the stream I/O functions take care of it automatically. When a new file is opened. After the read operation. The file input/output functions covered earlier make use of the position indicator. the position indicator is always at the beginning of the file. Compiled by Ergin TARI . if you want to read all the data in a file sequentially or write data to a file sequentially. and the next read operation begins there. use the C library functions that let you determine and change the value of the file position indicator. Thus.Lecture 11. you don't need to be concerned about the position indicator. you can perform random file access. The position indicator specifies where read and write operations take place in the file. if you open a file for reading. the position indicator is at the end of the file if the file was opened in append mode. When you need more control. Page 45 Sequential Versus Random File Access Every open file has a file position indicator associated with it. the position indicator is at position 10. any position in a file without reading or writing all the preceding data. although the manipulations go on behind the scenes. or at the beginning of the file if the file was opened in any other mode. you input the first 10 bytes in the file (the bytes at positions 0 through 9). The position is always given in terms of bytes from the beginning of the file.

The argument fp is the FILE pointer associated with the stream. The argument fp is the FILE pointer returned by fopen() when the file was opened. use ftell(). located in STDIO. To determine the value of a file's position indicator.H. ftell() returns -1L (a type long -1). reads long ftell(FILE *fp). The function ftell() returns a type long that gives the current file position in bytes from the start of the file (the first byte is at position 0). This function's prototype. After rewind() is called. If an error occurs. Its prototype.Lecture 11. is void rewind(FILE *fp). Use rewind() if you've read some data from a file and you want to start reading from the beginning of the file again without closing and reopening the file. use the library function rewind(). in STDIO. Compiled by Ergin TARI .H. Page 46 The ftell() and rewind() Functions To set the position indicator to the beginning of the file. the file's position indicator is set to the beginning of the file (byte 0).

/* Read in the next 5 characters. fp) == EOF) 21: { 22: fprintf(stderr."). printf("\nAfter reading in %s. /* Rewind the stream. Compiled by Ergin TARI . */ rewind(fp). 13: 14: if ( (fp = fopen("TEXT. printf("\n\nThe next 5 characters are %s."). */ fgets(buf. buf. BUFLEN. /* Read in 5 characters."). 8: 9: main() 10: { 11: FILE *fp. */ if ( (fp = fopen("TEXT. */ 2: #include <stdlib.TXT". the position is back at %ld". and position now = %ld". 23: exit(1). Page 47 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: } /* Now open the file for reading. buf.h> 4: 5: #define BUFLEN 6 6: 7: char msg[] = "abcdefghijklmnopqrstuvwxyz". "Error opening file. } printf("\nImmediately after opening. BUFLEN. ftell(fp)). "Error writing to file. ftell(fp)). "Error opening file. ftell(fp)).h> 3: #include <stdio. position = 0 After reading in abcde. the position is back at 0 and reading starts at the beginning again: abcde Lecture 11. 18: } 19: 20: if (fputs(msg. BUFLEN. position = 5 The next 5 characters are fghij. position = %ld". printf("\n\nAfter rewinding. "w")) == NULL) 15: { 16: fprintf(stderr. 24: } 25: 26: fclose(fp). fclose(fp). fp). fp). printf("\nand reading starts at the beginning again: %s\n". buf). */ fgets(buf.TXT". return(0). fp).1: /* Demonstrates ftell() and rewind(). 17: exit(1). exit(1). and position now = 10 After rewinding. ftell(fp)). "r")) == NULL) { fprintf(stderr. /* Read in 5 characters. 12: char buf[BUFLEN]. position = %ld". 27: Immediately after opening. */ fgets(buf.

Compiled by Ergin TARI . There can be three values for origin.Lecture 11.H. as shown in the following table. The function prototype. The argument fp is the FILE pointer associated with the file.H. is int fseek(FILE *fp. in STDIO. SEEK_CUR SEEK_END 1 2 Moves the indicator offset bytes from its current position. Moves the indicator offset bytes from the end of the file. int origin). with symbolic constants defined in IO. long offset. The distance that the position indicator is to be moved is given by offset in bytes. By using fseek(). The function fseek() returns 0 if the indicator was successfully moved or nonzero if an error occurred. Page 48 The fseek() Function More precise control over a stream's position indicator is possible with the fseek() library function. you can set the position indicator anywhere in the file. The argument origin specifies the move's relative starting point. Constant SEEK_SET Value 0 Description Moves the indicator offset bytes from the beginning of the file.

"). MAX.h> #include <stdio. int data. sizeof(int).DAT". Page 49 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: 33: 34: /* Random access with fseek(). count < MAX. "\nError writing data to file. */ if ( (fwrite(array. count++) array[count] = count * 10. } /* Write the array to the file. */ for (count = 0.Lecture 11. */ if ( (fp = fopen("RANDOM. count. /* Open a binary file for writing.h> #define MAX 50 main() { FILE *fp. "wb")) == NULL) { fprintf(stderr. long offset. /* Initialize the array. array[MAX]."). "\nError opening file. fp)) != MAX) { fprintf(stderr. */ #include <stdlib. exit(1). then close it. exit(1). } Compiled by Ergin TARI .

-1 to quit: 0 Element 0 has value 0. -1 to quit: 1 Element 1 has value 10. exit(1). -1 to quit: 49 Element 49 has value 490. (offset*sizeof(int)). &offset). -1 to quit: -1 fclose(fp).MAX-1). Enter element to read. sizeof(int). "rb")) == NULL) { fprintf(stderr. exit(1).35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: } fclose(fp). Enter element to read. return(0). 0-49. /* Move the position indicator to the specified element.DAT". } printf("\nElement %ld has value %d. */ while (1) { printf("\nEnter element to read. Input the element */ /* and display it. */ if ( (fp = fopen("RANDOM. else if (offset > MAX-1) continue. 0-49. */ fread(&data. scanf("%ld". Compiled by Ergin TARI . /* Open the file for reading."). "\nError opening file. */ if ( (fseek(fp. } /* Ask user which element to read. offset. 0-49. fp). if (offset < 0) break. -1 to quit: 6 Element 6 has value 60. 0-49. Enter element to read.". 0-49. -1 to quit: 5 Page 50 Element 5 has value 50. Enter element to read. data). -1 to quit: ". Enter element to read. 0-49. SEEK_SET)) != 0) { fprintf(stderr. Lecture 11. 1. quitting when -1 is entered. "\nError using fseek(). Enter element to read. } /* Read in a single integer."). 0-%d.

Its prototype is in STDIO. if you don't have sufficient access rights. if it's read-only. If the file exists.Lecture 11. or if some other error occurs. Compiled by Ergin TARI . and remove() returns 0. you use the library function remove(). (See the section on filenames earlier in this week. remove() returns -1. The variable *filename is a pointer to the name of the file to be deleted. it is deleted (just as if you used the DEL command from the DOS prompt or the rm command in UNIX).) The specified file must not be open. Page 51 Deleting a File To delete a file.H. If the file doesn't exist. as follows: int remove( const char *filename ).

bak Error deleting the file *. filename). filename).bak has been deleted. printf("Enter the filename to delete: ").\n".bak The file list1414.Lecture 11. */ #include <stdio. else fprintf(stderr. Page 52 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: /* Demonstrates the remove() function. } Enter the filename to delete: *. if ( remove(filename) == 0) printf("The file %s has been deleted. Compiled by Ergin TARI . gets(filename).h> main() { char filename[80]. return(0).\n".bak. "Error deleting the file %s. Enter the filename to delete: list1414.

You try to rename to another disk.Lecture 11. Compiled by Ergin TARI .H. Errors can be caused by the following conditions (among others): The file oldname does not exist. The only restriction is that both names must refer to the same disk drive. Page 53 Renaming a File The rename() function changes the name of an existing disk file. or -1 if an error occurs. The function rename() returns 0 on success. The function prototype. you can't rename a file to a different disk drive. const char *newname ). The filenames pointed to by oldname and newname follow the rules given earlier in this chapter. A file with the name newname already exists. is as follows: int rename( const char *oldname. in STDIO.

Page 54 : /* Using rename() to change a filename. 19: } Compiled by Ergin TARI . newname ) == 0 ) 15: printf("%s has been renamed %s. "An error has occurred renaming %s. */ 2: 3: #include <stdio.\n". 11: printf("Enter new name for file: "). Enter current filename: list1609. 18: return(0). 16: else 17: fprintf(stderr.h> 4: 5: main() 6: { 7: char oldname[80].c has been renamed rename. 13: 14: if ( rename( oldname. oldname). 10: gets(oldname). oldname.c 8: Enter new name for file: rename. newname).c. list1609.c 9: printf("Enter current filename: "). 12: gets(newname).Lecture 11. newname[80].\n".

and then loop back to step 3. Page 55 Copying a File It's frequently necessary to make a copy of a file--an exact duplicate with a different name (or with the same name but in a different drive or directory). but it's really quite simple thanks to C's use of streams for input and output. 4. 3. Open the source file for reading in binary mode.Lecture 11. you're done and can close both files and return to the calling program. and other operating systems have equivalents. 5. In DOS. Remember. This might sound a bit complicated. If you haven't reached end-of-file. the pointer is at the start of the file. Here are the steps you follow: 1. If the function feof() indicates that you've reached the end of the source file. so you need to write your own. Read a character from the source file. you do this with the COPY command. when a file is first opened. Open the destination file for writing in binary mode. so there's no need to position the file pointer explicitly. write the character to the destination file. How do you copy a file in C? There's no library function. not just text files. (Using binary mode ensures that the function can copy all sorts of files. Compiled by Ergin TARI .) 2.

h> 4: 5: int file_copy( char *oldname. 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: } /* Open the destination file for writing in binary mode. "wb" ) ) == NULL ) { fclose ( fold ). */ 2: 3: #include <stdio. write the byte to the */ /* destination. char *newname ). */ 30: 31: if ( ( fold = fopen( oldname. } fclose ( fnew ). "rb" ) ) == NULL ) 32: return -1. 10: 11: /* Get the source and destination names. */ while (1) { c = fgetc( fold ).Lecture 11. return 0. if ( !feof( fold ) ) fputc( c. char *newname ) 25: { 26: FILE *fold. */ 12: 13: printf("\nEnter source file: "). 22: return(0). return -1. fclose ( fold ). destination ) == 0 ) 19: puts("Copy operation successful").c Copy operation successful Compiled by Ergin TARI . if end of file */ /* has not been reached.c Enter destination file: tmpfile. 23: } 24: int file_copy( char *oldname. fnew ). *fnew. 14: gets(source). 27: int c. } /* Read one byte at a time from the source. 20: else 21: fprintf(stderr. Page 56 1: /* Copying a file. else break. 16: gets(destination). 17: 18: if ( file_copy( source. destination[80]. 28: 29: /* Open the source file for reading in binary mode. Enter source file: list1610. 6: 7: main() 8: { 9: char source[80]. */ if ( ( fnew = fopen( newname. "Error during copy operation"). 15: printf("\nEnter destination file: ").

A temporary file is a file that is created by the program. You can also pass a null pointer (NULL). Page 57 Using Temporary Files Some programs make use of one or more temporary files during execution. in which case the temporary name is stored in a buffer internal to tmpnam(). The C standard library includes a function tmpnam() that creates a valid filename that doesn't conflict with any existing file. and then deleted before the program terminates. All that is necessary is that you use a name that isn't already in use for another file. used for some purpose during program execution.H is as follows: char *tmpnam(char *s). Compiled by Ergin TARI . because it gets deleted. The arguments must be a pointer to a buffer large enough to hold the filename. you don't really care what its name is. When you create a temporary file.Lecture 11. and the function returns a pointer to that buffer. Its prototype in STDIO.

$$$ Temporary name 2: TMP2. buffer). c).h> 4: 5: main() 6: { 7: char buffer[10]. 12: 13: /* Get another name. 21: printf("\nTemporary name 2: %s\n". 17: 18: /* Display the names.$$$ Compiled by Ergin TARI . */ 19: 20: printf("Temporary name 1: %s".Lecture 11. 8: 9: /* Get a temporary name in the defined buffer. 22: } Temporary name 1: TMP1. Page 58 1: /* Demonstration of temporary filenames. *c. */ 15: 16: c = tmpnam(NULL). this time in the function's */ 14: /* internal buffer. */ 2: 3: #include <stdio. */ 10: 11: tmpnam(buffer).

The fgetc() and fputc() functions read or write one character at a time. a printer. The feof() function can determine when the end of a file has been reached. a stream is device-independent. is called a stream.Summary • • • • • • • • • • • • • • Lecture 11. The file position indicator in the FILE structure points to the position in a file where data will be read from or written to. There are two stream formats: text stream and binary stream. Page 59 In C. The fclose() function is responsible for closing an opened file and disassociating a stream with the file. a terminal. You can specify different modes for opening a file. The fopen() function is used to open a file and associate a stream to the opened file. Not like a file. or vice versa. Compiled by Ergin TARI . The fgets() and fputs() functions read or write one line at a time. The data flow you transfer from your program to a file. or a tape drive. A stream is a series of ordered bytes. In a binary file. the feof() function should be used to detect EOF. The fread() and fwrite() functions read or write one block of data at a time. a file can refer to a disk file.

Sign up to vote on this title
UsefulNot useful