Files

Oracle Certification Program Candidate Guide

So far, we have dealt with programs involving variables, arrays, structures and unions which are used for manipulating information resident in the main memory of the computer. Since information kept in the RAM is temporary in nature and is limited in size, it is often necessary to read and write data stored in the backup media, such as disk drive, magnetic tape drive. Data is stored in such devices in files and different types of file organisations have been proposed for efficient storage and retrieval of data.

C provides a wide spectrum of standard library routines to ensure data transfer between main memory of the computer (RAM) and external devices, such as terminal, printer, disk drives and tape drives. As mentioned before in Chapter 6, such external storage devices are treated as files and appropriate routines are called to perform read and write operations from those files. To maintain a uniform access method for different types of devices, C supports the concept of buffer which is a data structure that provides necessary logical interface to the external files.

12.1 OPENING AND CLOSING OF FILES

When working with stream oriented files, the first step is to establish a buffer area, where data can be temporarily stored while being transferred between system RAM and data file.

The buffer area is established by the following statement,

FILE *ptvar; /* ptvar is a file pointer*/

The FILE ( all capitals) is a typedef structure declaration and it is included in the stdio.h header file declarations. Hence any reference to FILE inside a program, requires the following statement.

# include

The typedef structure FILE is declared in stdio.h as follows.

typedef struct {

unsigned char *_ptr; /* pointer to next char*/

int _cnt; /*total character in buffer */

unsigned char *_base; /*pointer to logical buffer*/

char _flag; /*mode file opened in */

char _file; /*file descriptor*/

}FILE;

Hence the file pointer ptvar, points to the structure type FILE, that contains information about the file, such as the buffer location, the current character position in the buffer, a flag indicating the mode in which file is opened and a file descriptor. The members in the structure FILE, receive values only if the file is opened successfully using fopen function. The standard library function fopen takes up two arguments, a filename and a file type. The file type describes the various modes of operations (such as read, write, append or rewrite) possible on the file. The fopen, if successful, establishes connection between file pointer and the external name (file name). If a file cannot be opened, fopen returns NULL value to the file pointer.

ptvar=fopen (, );

The filename is typically a string variable or a string constant that represents the external name. The file type is again a string type variable that defines the manner in which file is to be used.

MODE

MEANING

“r”

“w”

“a”

“r+”

“w+”

“a+”

read only. If a file with the given filename does not exist, the file opening operation in this mode would fail.

write only. If a file with the given filename exists, its content will be destroyed and a new file will be created.

appends data to an already existing file. Creates the file if file with file name is not located on the disk.

updates the file by reading and writing the changed data into the file. Error occurs if the file does not exist.

opens a file for reading and writing. It always creates a brand new file destroying a file having same name it exists on the disk.

reading and appending to a file is possible in this mode. It creates a new file if the file has not already been created.

Table 12.1 : Different modes of opening files.

The fopen function allocates buffer and assigns the address of the same to the file pointer (ptvar) to support further input or output operations on the file. It is always desirable to free the file pointer when it is no longer needed, since every operating system puts some restrictions on the number of files that can be opened simultaneously. Closing of a file or in other word releasing the buffer that establishes connection to the external name (filename) is performed by the standard library function fclose. If an already opened file needs to be processed in a different mode it is always a better practice, to close the file and to reopen it again in the desired mode. The syntax of fclose is as shown below :

fclose (ptvar);

Example 12.1 :

#include

main()

{

FILE * fpt;

fpt = fopen (“dummy.ext”, “w”);

if (fpt == NULL)

printf (“\n Error - the file cannot be opened \n”);

else

{

/* perform operations on files */

}

fclose (fpt);

}

12.2 CREATING A DATA FILE - USING CHARACTER BASED FILE I/O FUNCTION

The following program creates a file taking keyboard input and displays the file content on the monitor. The input stream is terminated by the user by pressing ^d ( + d) keystroke combination.

Example 12.2 :

# include

main()

{

FILE *fp;

char ch;

fp=fopen(“some.fil”, “w”); /*opens some.fil in output mode */

/* accept one character from keyboard and write onto the file */

/* stdin (parameter to getc) is a file pointer associated with keyboard buffer */

while((ch=getc(stdin)) != EOF)

putc(ch,fp);

/* closing the file to reopen in input mode again */

fclose(fp);

fp=fopen(“some.fil”, “r”);

printf(“\n\n Displaying the content of the file\n”);

while((ch=fgetc(fp)) != EOF)

printf(“%c”,ch);

fclose(fp);

}

The above program uses the function getc and putc to get one character from the keyboard (stdin is the address of the buffer associated with the keyboard) and writing onto the file to be created (i.e some.fil opened in output mode) respectively. The function getc reads a character from the file pointed to by the file pointer, which is passed as a parameter to it. Any attempt to read the character beyond the last character of the file leads to end of file situation. The symbolic constant EOF defined in the header file stdio.h with the value of -1, represents the return status of an unsuccessful read attempt made by getc function. Alternatively the same program can be written using two other standard library functions fgetc and fputc.

FILE *fp1, *fp2;

/*assume fp1 is associated with file opened in read and fp2 in write mode */

while ((ch = fgetc(fp)) != EOF)

fputc (ch,fp2);

The file pointer provides important information regarding the manner in which input/output operations take place in a file. It is very important to keep track of the position from where the next attempt for any I/O operation can be initiated. A logical pointer does that job (the second member of the FILE structure). We explain the steps with a file anyfile.txt which contains a line of text “This is a sample text file”.

fpt=fopen (“anyfile.txt”, “r”);

The fopen statement will set the pointer to the starting byte of the file.

Here

the offset is 0, and

the current position is 1;

file pointer

¯

T

h

i

s

a

s

a

m

p

l

e

t

e

x

t

f

i

l

e

The current position is the starting byte of the file from where next request of I/O operation starts. At this point the offset is 0 bytes (offset is determined by number of bytes that precede the current position). The offset position of a file can be determined using ftell standard library function that takes the file pointer as parameter. The getc function shifts the file pointer to the next character position in the text stream.

ch=getc(fpt);

The above statement will read one character from the file into the variable ch.

Here

the offset is 1, and

the current position is 2;

¯

T

h

i

s

a

s

a

m

p

l

e

t

e

x

t

f

i

l

e

STRING I/O FUNCTIONS - fgets, fputs

C supports string based I/O operations using fgets (input) and fputs (output) functions. The behaviours of these two functions are quite similar to the gets and puts functions, discussed earlier. The differences can be seen from the following declaration,

fgets (, , );

fputs (, );

The function fgets reads characters including embedded spaces from the file pointed to by the file pointer and stores that in the string. The maximum number of characters read would be equal to length -1, since one character position is kept aside for null (‘\0’) terminator. While reading from a file, fgets automatically puts a null terminator at end of the string as soon as it encounters ‘\n’ or newline in the input text stream. The fgets returns NULL (symbolic constant defined in stdio.h with a 0 value), if read attempt fails (may be due to end of file being encountered).

Example 12.3 :

/* Copying a file to an another file */

# include

main()

{

FILE *fp1,*fp2;

char line[81];

if((fp1=fopen(“input.fil”, “r”)) == NULL)

{

printf(“\nError ! the file %s cannot be opened\n”);

exit();

}

fp2=fopen(“output.fil”, “w”);

while(fgets(line,81,fp1) != NULL)

fputs(line,fp2);

fclose(fp1);

fclose(fp2);

fp2=fopen(“output.fil”,”r”);

printf(“\n\n Displaying the content of the file just created\n”);

while(fgets(line,81,fp2) != NULL)

printf(“%s\n”,line);

fclose(fp2);

}

1. Identify the errors (if any) in the following programs,

a. # include

main()

{

FILE *fp;

char ch;

while((ch=getchar())!=EOF)

fputc(ch,fp);

fclose(fp);

}

b. # include

main()

{

FILE *fp1,*fp2;

char ch;

fp1=fopen(“in.dat”, “w”);

fp2=fopen(“out.dat”, “r”);

while((ch=fgetc(fp1))!=EOF)

fputc(ch,fp2);

fclose(fp1);

}

2. The skeletal outline of a C program is shown below.

#include

main ( int argc, char *argv[] )

{

FILE *fp;

int x;

float y;

char z;

fp=fopen (“some_fil.inf”,“r”);

...

fclose(fp);

}

Introduce appropriate statements to read the values of the variable x, y and z from the file “some_fil.inf” and display them on the screen.

3. The following program after reading a stream of characters from an existing file, displays it on the screen and writes onto a new file.

#include

/* read a stream of characters from a file whose name is supplied as a command line argument, display it on the screen and write it onto a new file */

main (int argc, char *argv [ ])

{

FILE *fp1, *fp2;

char chr;

/* open the existing file supplied as a command line parameter in the read mode */

if (( fp1 = fopen(argv[1], “r”)) == 0)

printf(“\nERROR - Cannot open the indicated file \n”);

/* read and display each character form the file and then write it onto another file supplied as the second command line parameter. */

else

{

fp2 = fopen(argv[2], “w”);

while(c != ‘\n’)

{

putchar(chr=getc(fp1));

putc(chr, fp2);

}

}

/* close the data files */

fclose(fp1);

fclose(fp2);

}

Suppose the object program is stored in a file called copy.exe. The existing data is stored in a file called old_file and the new file to be created is new_file. Show how the command line would be written to execute this program.


12.3 STRUCTURE BASED I/O FUNCTIONS - fread and fwrite

The function fread and fwrite can read and write structures from and into a file respectively. While writing, the function fwrite compresses the numerical data, that is why files thus created differ from an ordinary text file. A file created by fwrite can successfully be read using fread function. The prototypes of these function declarations are described below :

fread(,,,);

fwrite(,,,);

Not only structures, any sort of data object can be transferred from the buffer to the file or vice versa during input or output operations. For example, we can write an integer variable marks onto a file (fp is associated file pointer) by the following statement,

fwrite(&marks, sizeof(int), 1, fp);

Here, we show two ways to perform input or output operations with structures. The first one involves a simple structure variable, whereas the second one uses pointers to structures.

Method 1:

Consider the structure student used in the example 10.1,

student first;

fread(&first, sizeof(student),1,fp); /* reads one student record */

Method 2:

student *ptr;

ptr=(student *)malloc(sizeof(student));

fread(ptr,sizeof(student),1,fp);

The fread function returns the number of data blocks read successfully at the end of the input operation. The return value helps in evaluating the state of affairs as shown below.

if(fread(ptr,sizeof(student),1,fp) == 1)

{

/* the record is successfully read */

}

else

{

/* unsuccessful read attempt */

}

The fread function cannot communicate the occurrence of end of file. To do that we use an another library function feof to trap the end of file.

4. Consider the following C program (skeletal) :

#include

struct data {

int i;

float f;

char c;

}dt;

main ( )

{

FILE *p1, *p2;

p1 = fopen (“old.fil”, “r”);

p2 = fopen (“new.fil”, “w”);

....

fclose(pt1);

fclose(pt2);

}

Include suitable read and write statements to do the following :

a) Read the structure data from the file old.fil.

b) Display each of structure member’s value on the screen and change the value.

c) Write the new values to the data file new.fil.


12.4 CHECKING OF END OF FILE USING feof()

The fread function returns the number of data blocks read at the completion of a successful read operation. But when the function does not respond properly (returns no specific value) e.g. when the end of file is encountered, the standard library function feof function should be used to detect such occasions. The function helps in trapping the occurrence of end of file and thus enhances program efficiency.

12.5 REPOSITIONING FILE POINTER - fseek() and rewind()

The standard library function fseek enables direct access to data items in a stream. The function sets the file pointer to a new position, from where the subsequent read or write operations begin. The fseek function prototype,

fseek(file_pointer, long offset, int origin);

uses three arguments to reposition the file pointer to a place determined by the offset field starting from the position indicated by the parameter, origin. The origin may be either 0 ( to indicate start point to be the beginning of the file), 1 (the origin is the current file pointer position), or 2 (indicates end of file). The function fseek returns non-zero value on error.

If one intends to initiate subsequent operations from the beginning of the file (whatever may be the current position), the function rewind helps in achieving that. The rewind expects the file pointer as the only argument,

rewind(file_pointer);

The effect created by the previous statement can be simulated using the following call to fseek function,

fseek(file_pointer,0L,0);

Example 12.4 :

/*demonstration of fseek, feof, fread and fwrite function */

# include

typedef struct {

char name[21];

char tel[10];

} tele;

tele *t;

main()

{

FILE *fp;

char rp=‘ ’,nm[21];

fp=fopen(“tele.dat”, “a”);

while(rp != ‘n’ && rp != ‘N’)

{

t=(tele *)malloc(sizeof(tele));

printf(“\n Enter name :”);

gets(t->name);

fflush(stdin);

printf(“|n Enter telephone number :”);

gets(t->tel);

fflush(stdin);

fwrite(t,sizeof(tele),1,fp);

printf(“Continue ?”);

rp=getchar();

fflush(stdin);

}

fclose(fp);

fp=fopen(“tele.dat”, “r+”);

rp=‘ ’;

while(rp != ‘n’ && rp != ‘N’)

{

printf(“\n Enter name for whom the data is to be modified :”);

gets(nm);

fflush(stdin);

t=(tele *) malloc(sizeof(tele));

while(1)

{

fread(t,sizeof(tele),1,fp);

if(!feof(fp))

{

if(strcmp(nm,t->name) == 0)

{

printf(“Enter new number :”);

gets(t->tel);

fflush(stdin);

fseek(fp, -sizeof(tele),1);

fwrite(t,sizeof(tele),1,fp);

break;

}

else

{

printf(“\nNo such subscriber .........EOF encountered\n”);

free(t);

break;

}

}

printf(“Continue ?”);

rp=getchar();

fflush(stdin);

}

fclose(fp);

}

5. Match the followings :

i) FILE a. checks for eof

ii) fseek(file_pointer,0L,0); b. is a symbolic constant defined in stdio.h

iii) feof() c. opens the file

iv) ftell() d. positions the file pointer to the top of the file.

v) fopen e. typedef structure defined in stdio.h

vi) EOF f. returns the ofset byte position

6. Identify the current position of the file pointer and the number of offset bytes from the beginning of the file to the current position of the file pointer after execution of the each of the following statements.

i) fp=fopen(“text.dmo”, “r”);

ii) fgets(word,21,fp);

iii) fseek(fp,-5l,1);

iv) fputs(new_word,fp); /* new_word is 5 characters long including ‘\0’ */

v) fseek(fp,0l,2);

vi) fseek(fp,15L,0);


0 comments: