0% found this document useful (0 votes)
3 views

File Operations

Uploaded by

Dr D Suneetha
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

File Operations

Uploaded by

Dr D Suneetha
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 9

MACROS

Macros are very common and often used in ‘C’ programming language to declare constants like strings,
addresses, or any other values such as maximum number of elements in an array and so on.
Before a C program is compiled, it is passed through another program is called preprocessor.
Preprocessor is a smart editor. It inserts, includes, excludes and replaces text based on commands
supplied by the programmer.
For those who are not familiar with them, Macros are declared by the #define keyword. Macros are
also used to define some basic functionality given a set of one or more typeless parameters, similarly to
an inline function in c++.
Preprocessor extends the power of ‘C’ programming language. Line that begin with # are called
preprocessing directives.
Use of #include
Let us consider very common preprocessing directive as below:
#include <stdio.h>
Here, “stdio.h” is a header file and the preprocessor replace the above line with the contents of
header file.
Use of #define
Preprocessing directive #define has two forms. The first form is,
#define identifier token_string
token_string part is optional but are used almost every time in program.
Example
#define c 299792458 /*speed of light in m/s */
The token string in above line 2299792458 is replaced in every occurrence of symbolic constant c.
‘C’ Program to find area of a cricle. [Area of circle=]
#include <stdio.h>
#define PI 3.1415 /* During preprocessing every occurrence of PI is replaced by 3.1415 */
main()
{ int radius;
float area;
printf(“Enter the radius: “);
scanf(“%d”,&radius);
area=PI*radius*radius;
printf(“Area=%.2f”,area);
}
Output
Enter the radius: 3
Area=28.27
# include<stdio.h> This format is used to direct the processor to include header file stdio.h from the
system library.
#include “filename.h” This format makes preprocessor look for the header files in the user defined
directory.
Benefits by using Macros
1. Code Maintainability: Using a macro to define a constant provides an easy and correct method to
ensure that if this value needs to be updated; all instances of this value will be automatically
updated. Otherwise, the program may behave incorrectly, and even crash.
2. Code Readability: Specifying a macro name is much more readable and understandable to someone
who needs to read the code, than a plain number or address.
Disadvantages by using Macros
1. Hard to Extend: If the macros become complex and a change is required, any errors you introduce
may yield vague compilation errors by the compiler, and always, the error line number points to the
start of the macro.
2. Hard to Debug: Debuggers often do not provide clear access and step ability to a code inside
macros.
Important Points about Macros
1. Macros are expanded from the top of the file, to the bottom.
2. Macros can be defined, undefined and then redefined.
3. Macros, unlike other code, are not being compiled. You can write junk stuff as a macro and the file
will be compiled. Due to the same reason, macros can contain any text, even if it is not declared or
defined yet.
4. Macros are expanded only when used in the code. If you’ll use a junk macro in the code, it will be
converted to junk which will fails your compilation.
5. Macros can span over only a single line. The only way to extend a macro to another line is by adding
a continuation token ‘\’ in the end of the line. No other character is allowed after the new line
marker. i.e., continuation to key(1) must immediately followed by a newline. If any white space is
present between (\) and newline then backslash is not a continuation token. EX: # define END\
printf(“Normal End”);
6. You can always inspect the expanded macros by using the same compilation command, with the
addition of the -E parameter. The output in this case, will be the preprocessed source code, where all
the macros are expanded.
Macro Functions: A function that accept parameters and return values are called macro functions. To
create a macro function, simply define a macro with a parameter that has whatever name you like, such as
my_Val. For example, one macro defined in the standard libraries is abs, which returns the absolute value
of its parameter. Let us define our own version, ABS below. (Note that we are defining it in upper case
not only to avoid conflicting with abs, but also because all macros should be defined in upper case, in the
GNU coding style).
# define ABS (my_Val) ((my_Val) <0)?-(my_Val): (my_Val)
This macros uses the ‘? …..’command to return a positive number, no matter what value is assigned
to my_Val is defined as a positive number. The macro returns the same number, and if my _Val is
defined as a negative number the macro returns its negative (which will be positive). If you write ABS (-
4), then the preprocessor will substitute -4 for my_Val. Macros can take more than one parameter, as in
the code example below.
One condition is that Macros are substituted in the program when it is used. This is potentially a
huge amount of code repetition. The advantage of a macro over an actual function is speed, no time is
taken up in passing control to a new function, because control never leaves the home function. The macro
just makes the function a bit longer.
A second condition function calls cannot be used as macro parameters. The following code will not
work:
ABS (cos (36))
Program-13
# include <stdio.h>
#define STRING1 “Spectrum\n”
#define STRING2 “must be all on one line!\n”
#define EXPRESSION1 1+2+3+4
#define EXPRESSION2 EXPRESSION1+10
#define ABS(x) ((x) <0?-(x): (x)
#define MAX(a, b) (a<b)?(b): (a)
#define BIGGEST(a, b, c) (MAX (a, b)<c)?(c) : (MAX(a, b))\
int main ()
{
printf (STRING1);
printf (STRING 2);
printf(“%d/n”, EXPRESSION1);
printf(“%d/n”, EXPRESSION2);
printf(“% d/n”, ABS(-10));
printf (“Biggest of 1, 2, and 3 is %d\n”, BIGGEST(1, 2,3));
return 0;
}
Output
Spectrum
must be all on one line!
10
20
10
Biggest of 1, 2 and 3 is 3
Macros with Argument: Preprocessing directive #define can be used to write macro definitions with
parameters as well in the form below:
#define identifier(identifier 1,.....identifier n) token_string
Again, the token string is optional but, are used in almost every case. Let us consider an example of
macro definition with argument.
#define area(r) (3.1415*r*r)
Here, the argument passed is r. Every time the program encounters area(argument), it will be replace
by (3.1415*argument*argument). Suppose, we passed (r1+5) as argument then, it expands as below,

area(r1+5) expands to (3.1415*(r1+5)(r1+5)).


FILE OPERATIONS
Following are some of the file operations in C.
1. Opening a file 2. Reading a file
3. Writing to a file 4. Closing a file
Most of the compiler support file handling functions. When working with a standard data file, first to
create the buffer area(the portion of main memory is buffer which can be directly accessed by the I/O
devices), where the information stored temporarily during transfer between the computer’s memory and
the data file. The buffer area helps in fast read/write operation from/to the data file. The buffer area can be
associated by load like this.
Example: FILE *fptr;
Where, FILE (use uppercase letters only) is a special structure which is defined within stdio.h. As of
my experience it is not a good practice to use the fields of the FILE structure is,
typedef struct {
short level; /* fill/empty level of buffer */
unsigned flags; /* file status flags */
char fd; /* file descriptor (handle) */
unsigned char hold /* ungetc char if no buffer */
short bsize; /* buffer size */
unsigned char *buffer,*curp; * data transfer buffer, Current active
pointer
*/
unsigned istemp; /*temporary file indicator */
short token; /*used for validity checking */
} file; /* file object */
fptr is the pointer returned by fopen() when a file is opened. It is function which returns the character
that was input (or) it return EOF on error. fptr is a pointer variable that indicates the starting location of
the buffer area. It is also known as a stream pointer or stream. The type of the file should specify and it
could be think like abstract data structure, whose details are hidden from us.
File is some of template which holds the information about the file (file attributes).
9.6.1 Opening File
1. Opening File: A data file must be opened before it can be created or processed. The filename is
associated with the buffer area or the stream. The mode of file utilization i.e., read only, writes only or
read/write both is also specified while opening the data file.
In order to open a file, use the library function fopen() is given below
fptr=fopen(“filename”, ”mode”);
Where, filename represents the name of the file on disk /tape etc.(including a path like c://c/course if
necessary).
The mode is a string representing why you want to open the file. The filename must be in
accordance with the rules for naming files, as for naming files, as per the operating system use.
The fopen() returns a FILE *it can be used to access the file. You can get the message like “don’t
have permission or it doesn’t exist” if the file is not opened otherwise fopen() will return NULL value is
returned which is defined in stdio.h. These are the other modes you can use operating a file are,
Mod Purpose
e
r Open for reading only. The file must already exist.
w Open for writing only. If the file already exists, its contents will be lost. If it does not exist, it
will be created.
a Open for appending (i.e., for adding data to the end of the existing file). If it does not exist, it
will be created.
r+ Open a file for both reading and writing. The file must already exist.
w+ Create a file for both reading and writing. If the file exists, its contents are overwritten.
a+ Open for both reading and appending. If the file does not exist, it will be created.
The pointer to the structure type FILE is assigned to fptr.
If you are going to handle binary files then you will use below mentioned access modes instead of
the above mentioned:
“rb”, ”wb”, ”ab”, ”ab+”, ”a+b”, ”wb+”, ”w+b”, ”ab+”, ”a+b”
Example
#include<stdio.h>
main( )
{ FILE*fp ;
fp = fopen (“ file.c”,”r”) ;
if( fp == NULL )
{ puts (“cannot open file”) ;
exit() ;
} }
In the above example, file.c is filename and r is reading access mode.
The file contains the following information
i. Name of the file to open from storage device.
ii. Path, tells where the file is located. If path is omitted, it takes default path as current working
directory from where the application is executed.
iii. Maximum length of a file name is 8 characters long and can have extension of 3 characters.
iv. The period (.) which separates file name and extension.
v. Extension tell about type of file.
vi. File name or extension should contain only alphabets, numbers or underscore mode specifies what
kind of operation want to do with the file. A list of file opening modes.
Reading from a file is nothing but an input operation i.e., it gets the data from the file.
A file contains the following information
i. Once the file has been opened for reading using fopen( ), the file’s contents are brought into memory
and a pointer points to the first character.
ii. This file functions are ch = fgetc (fp) ; fgetc( ). These are read the character from current pointer
position, advances the pointer position. So that it now points to the next character, and returns the
character that is read, which we collected in the variable ch. Note that once the file has been opened,
we refer to the file through the file pointer fp.
iii. We have to use the function fgetc( ) within an indefinite while loop. There has to be a way to break
out of this while, it is the moment we reach the end of file.
iv. While reading from the file, when fgetc( ) encounters this special character, instead of returning the
character that it has read, it returns the macro EOF.
Example: Let us consider an example for opening files
main()
File *ifp,*ofp;
char *mode=“r”;
char outputfilename [ ]=“out.list”;
ifp=fopen (“in.list”,mode);
if (ifp==NULL)
{ fprintf (stderr, “can’t open input file in. list!\n”);
exit(1);
}
ofp=fopen (outputFilename,”w”);
if(ofp==NULL)
{ fprintf(stderr, “Can’t open file %s!\n”, outputfilename );
exit (1);
}
Where ifp= input file pointer
Ofp : output file pointer
The input file opening for reading (“r”) must already exist. The output file opening writing (“w”)
does not have to exist. If not already it will be lost and new content will be added(i.e., overwritten).
9.6.2 Reading File
First the file should be opened and if has been successfully opened, you can read from it using fscanf()
(or)write to it using fprintf(). These functions are similar to scanf() and printf(), except they require an
extra first parameter, a FILE * for the file to be read/write.
Example: Let us continue previous example.
Suppose the input file consists of lines with a username and an integer test score.
in.txt: username test score
Milky 70
Dolly 60
And that each username can be allowed maximum 8 characters.
char username[9]; /* one extra for null char as per the limitation of username size
int score;

while (fscanf (ifp,”%s %d”, username, &score) !=EOF)
{ fprintf(ofp,”%s %d\n”, username, score);
}

The function fscanf(), like scanf(), normally returns the number of values it was able to read in.
However, when it hits the end of the file, it returns the number of values it was able to read in. However,
when it hits the end of the file, it returns the special value EOF.
9.6.3 Writing to a File
Writing to a File: Writing to a file is nothing but an output operation i.e., it gets the data from the file.
Example
#include<stdio.h>
void main( )
{ FILE *fs, *ft ;
char ch ;
fs = fopen ( “file1.c”, ‘r’ ) ;
if ( fs = = NULL )
{ puts ( “Cannot open source file” ) ;
exit( ) ;
}
ft = fopen ( “file2.c”, ‘w’ ) ;
if ( ft = = NULL )
{ puts ( “Cannot open target file” ) ;
fclose ( fs ) ;
exit( ) ;
}
while (1)
{ ch = fgetc ( fs ) ;
if ( ch = = EOF )
break ;
else
fputc ( ch, ft ) ;
} fclose ( fs ) ;
fclose (ft)
} }
Output
Cannot open the source file

9.6.4 Closing Files


After finishing reading or writing to a file it has to be closed. File closing functions are:
A file must be closed as soon as all operations on it have been completed. This ensures that all
outstanding information associated with the file is flushed out from the buffers and all links to the file are
broken. It also prevents any accidental misuse of the file. In case, there is a limit to the number of files
that can be kept open simultaneously, closing of unwanted files might help open the required files.
Another instance where we have to close a file is when we want to reopen the same file in a different
mode. The I/O library supports a function to do this for us. It takes the following form:
fclose(file_pointer);
closing a file is very important, especially with output files, Because of the often buffered. It may
not written to disk right away. But may end up in a buffer may hold the text temporary as shown below.
The buffer is really just 1-dimentional array
When the file then is closed, the data is finally written to secondary devices like disk/tape etc.
This would close the file associated with the FILE pointer file_pointer. Look at the following
segment of a program.
main()
{
FILE *p1, *p2;
p1 = fopen(“INPUT”,txt ‘w’);
p2 = fopen(“OUTPUT”, txt‘r’);
fclose(p1);
fclose(p2);
}
This program opens two files and closes them after all operations on them are completed.
Once a file is closed, its file pointer can be reused for another file. As a matter of fact all files are
closed automatically whenever a program terminates.
Special File Pointers: There are 3 special FILE *s that are always defined for a program. They are stdin
(standard input), stdout (standard output) and stderr (standard error).
Standard Input: Standard input is where things come from when you use scanf(). In other words,
scanf(“%d’, &val);
is equivalent to the following fscanf():
fscanf(stdin, ”%d”, &val);
Standard Output: Similarly, standard output is exactly where things go when you use printf (). In other
words,
printf(“value=%d\n”,val);
is equivalent to the following fprintf():
fprintf(stdout, “value=%d\n”, val);
Example
#include<stdio.h >
main( )
{ FILE *f1;
printf(“Data input output”);
f1=fopen(“INPUT.txt”, ‘w’); /*Open the file Input*/
while((c=getchar())!=EOF) /*get a character from key board*/
putc(c,f1); /*write a character to input*/
fclose(f1); /*close the file input*/
printf(“\n Data output \n”);
f1=fopen(“INPUT.txt”, ‘r’); /*Reopen the file input*/
while((c=getc(f1))!=EOF)
printf(“%c”,c);
fclose(f1); }
9.6.5 State of File
Creating a File: To bring a file into existence, the create system call is used. When this system call is
used, the oprating system searches for the free space in the file system and allocates it to the file. In
addition, the operating system makes a directory entry to record the name, location and other information
about the file.
Seeking a File: To position the pointer to a specific position in a file, the seek system call is used. Once
the pointer is positioned, data can be read from and written to that position.
Deleting a File: When a file is not required, the delete system call is used. The operating system searches
the file name in the directory listing. Having found the associated entry, it release all space allocated to
the file (that can be reused by other files) by arising its corresponding directory entry.
Appending a File: To add data at the end of an existing file, append system call is used. This system call
works similar to the write system call, except that it positions the pointer to the end of file and then
performs the write operation.
Renaming File: To change the name of an existing file, rename system call is used. This system call
changes the existing entry for the file name in the directory to a new file name.

You might also like