Formatted Disk I/O Functions
For formatted reading and writing of character, string, integer, float, there exist two functions, fscanf( ) and fprintf( ). Their prototypes are as follows:
int fprintf(FILE *fp, const char *control_string,…);
int fscanf(FILE *fp, const char *control_string,…);
where fp is a file pointer returned by a call to fopen( ). fprintf( ) and fscanf( ) direct there I/O operations to the file pointed to by fp. There exist no standard library functions to read or write numbers under the category of unformatted, text I/O function.
EXM 06: Write a program to accept some records of students consisting their name, roll number, percentage of marks obtained and write them onto disk file in append mode. At last print all records of the file.
# include
# include
# include
# include
int main(void)
{
FILE *fp;
char name[25];
int roll;
float per;
fp=fopen("INFO.TXT", "a+");
if(!fp)
{
printf("\n File openning error");
exit(1);
}
printf("\n\t Now give records to insert:-\n");
do
{
printf("\n\n Give NAME(single word): ");
fflush(stdin);
gets(name);
printf("\n Give ROLL: ");
scanf("%d",&roll);
printf("\n Give PERCENTAGE: ");
scanf("%f",&per);
fprintf(fp,"%s %d %f\n",name,roll,per);
printf("\n\t Have more record(Y/N)? ");
}while(toupper(getche())!='N');
rewind(fp);
printf("\n\t Now view the records of the file:-\n");
while(fscanf(fp,"%s %d %f",name,&roll,&per)!=EOF)
/*Donot use while(!feof(fp))*/
printf("\n%s %d %.2f",name,roll,per);
return 0;
}
getw( ) and putw( )
These are two binary mode functions, so open the file in binary mode. This two functions are used for efficient use number manipulation in file, otherwise these these two functions are useless.
- int getw(FILE *stream); - getw( ) returns the next integer in the named input stream. It assumes no special alignment in the file. getw( ) should not be used when the stream is opened in text mode.
- int putw(int w, FILE *stream); - putw( ) outputs the integer w to the given stream. It does not expect (and does not cause) special alignment in the file.
Return Value:
On success,
getw( ) returns the next integer on the input stream.
putw( ) returns the integer w.
On error,
getw( ) returns EOF
putw( ) returns EOF
On end-of-file, getw( ) returns EOF
Because EOF is a legitimate value for getw( ) to return, use feof( ) to detect end-of-file or ferror( ) to detect error. Because EOF is a legitimate integer, use ferror( ) to detect errors with putw( ).
EXM 07: Write a program to accept some integers and store them in a file using putw() function and then read the file. Use getw() function to read the specified file.
# include
# include
# include
int main(void)
{
FILE *fp;
char fln[15];
int x;
printf("\n Give the file name: ");
scanf("%s", fln);
fp=fopen(fln, "wb+");
if( !fp )
{
printf("\n File opening error");
exit(1);
}
do
{
printf("\n Give the number: ");
scanf("%d", &x);
putw(x, fp);
printf("\n\t Want to continue(Y/N)? ");
}while(toupper(getche())!='N');
rewind(fp);
printf("\n The integer content of the file:-\n");
while((x=getw(fp))!=EOF)
printf(" %d", x);
fclose(fp);
return 0;
}
EXM 08: Suppose there is a file by the name of INTEGERS.TXT containing integers. Write a program to transfer all odd and even integers from that file into the ODD.TXT and EVEN.TXT files respectively.
# include
# include
void main(void)
{
FILE *fs, *fe, *fo;
int x;
fs=fopen("INTEGERS.TXT","rb");
fe=fopen("EVEN.TXT","wb");
fo=fopen("ODD.TXT","wb");
if(!fs||!fe||!fo)
{
printf("\n File opening error");
exit(1);
}
while((x=getw(fs))!=EOF)
{
if(x%2==0)
putw(x,fe);
else
putw(x,fo);
}
printf("\n File manipulation complete .....");
fcloseall();
}
Text Vs. Binary Mode
As yet we have dealt with TEXT mode, but there exists another mode called BINARY mode to deal with file opening. There are three main areas where text and binary mode files are different:
- The handling of newlines: In text mode, a newline character is converted into the carriage return – linefeed combination before being written to the disk. Likewise, the carriage return – linefeed combination on the disk is converted back into a newline when a C program reads the file. But, if a file is opened in binary mode, as opposed to text mode, these conversions will not take place. As a result, a character count program, where the file is opened in text mode, shows less number of characters than if the file would have been opened in binary mode. The binary mode value is exactly same as that reported by the DIR command.
- The representation of end of file: In text mode, a special character (EOF), whose ASCII value is 26, is inserted after the last character in the file to mark the end of file. In binary mode no such special character is used to mark the end of file. The binary mode files keep track of the end of file from the number of characters present in the directory entry of the file. Due to this difference, if a file stores numbers in binary mode, it is important that binary mode only be used for reading the number back, since one of the numbers we stored might be the number 26. If this number is detected while we are reading the file by opening it in text mode, reading would be terminated before actual termination of the file. Hence, two modes are not compatible.
The storage of numbers: The only function that is available for storing numbers in a disk file is the fprintf( ) function. If we use this function then, text and characters are stored one character per byte. But the numbers are not stored as they are in memory (two bytes for an integer, four bytes for an float, and so on). Numbers are stored as string of characters. Thus, 1234, even though it occupies two bytes in memory, when transferred to the disk using fprintf( ),it would occupy four bytes, one byte per character. Similarly, the floating-point number 1234.56 would occupy 7 bytes on disk. On the other hand if the file is opened in binary and use those functions that store the number in binary format, each number would occupy same number of bytes on disk as it occupies in memory.
Functions for Binary File I/O
size_t fread(void *ptr, size_t size, size_t n, FILE *stream);
** Remarks: fread reads a specified number of equal-sized data items from an input stream into a block.
** Argument | What It Is/Does
-----------------------------------------------------
ptr | Points to a block into which data is read
size | Length of each item read, in bytes
n | Number of items read
stream | Points to input stream
** The total number of bytes read is (n * size).
** Return Value: On success, fread returns the number of items (not bytes) actually read. On end-of-file or error, fread returns a short count (possibly 0).
size_t fwrite(const void *ptr, size_t size, size_t n, FILE*stream);
** Remarks: fwrite appends a specified number of equal-sized data items to an output file.
** Argument | What It Is/Does
-------------------------------------
ptr | Pointer to any object; the data written begins at ptr
size | Length of each item of data
n | Number of data items to be appended
stream | Specifies output file
** The total number of bytes written is (n * size)
** Return Value: On success, returns the number of items (not bytes) actually written. On error, returns a short count.
** Returns the current file pointer
** Declaration:
long ftell(FILE *stream);
** Remarks: ftell returns the current file pointer for stream. If the file is binary, the offset is measured in bytes from the beginning of the file. The value returned by ftell can be used in a subsequent call to fseek.
** Return Value: On success, returns the current file pointer position. On error, returns -1L and sets errno to a positive value.
int fseek(FILE *stream, long offset, int whence);
** Remarks: fseek sets the file pointer associated with a stream to a new position.
** Argument | What It Is/Does
------------------------------------------------------------------------
stream | Stream whose file pointer fseek sets
offset | Difference in bytes between whence (a file pointer position)
and new position. For text mode streams, offset should be 0 or
a value returned by ftell.
whence | One of three SEEK_xxx file pointer locations (0, 1, or 2)
** Return Value: On success (the pointer is successfully moved), fseek returns 0. On failure, fseek returns a non-zero value. fseek returns an error code only on an unopened file or device.
** Constant | Value | File location
----------------------------------------------------
SEEK_SET | 0 | Seeks from beginning of file
SEEK_CUR | 1 | Seeks from current position
SEEK_END | 2 | Seeks from end of file
EXM 09: Write a program to create a file containing information of employees such as there name, designation, total salary, etc. Insert some employees' details onto the file using fwrite( ) and finally print these information in tabular form using fread( ) function.
# include
# include
# include
# include
# include
struct employee
{
char name[30];
float sal;
};
typedef struct employee EMP;
void main (void)
{
EMP a;
FILE *fp;
double dummy=sin(0.0);
dummy++;
clrscr();
fp=fopen("EMP.BIN", "wb+");
if(!fp)
{
printf("\n File opening error!!");
exit(1);
}
printf("\n Give info. of employees:-");
do
{
printf("\n\n Give NAME: ");
fflush( stdin );
fgets(a.name, 30,stdin);
printf("\n Give SALARY: ");
scanf("%f", &a.sal);
fwrite( &a, sizeof(a), 1, fp );
printf("\n Have more (Y/N)? ");
} while( toupper(getche()) != 'N' );
rewind(fp);
printf("\n\n Information of the employees in the file:-");
while( fread(&a, sizeof(a), 1, fp) == 1 )
{
a.name[strlen(a.name)-1]='\0';
printf("\n %s %.2f", a.name, a.sal);
}
getch();
fclose(fp);
}
If you have any problem email me: jayanta4u2006@gmail.com