Module 5
Module 5
File
File is a place on disk where data is stored. There are two different types of data files,
text files: Text files store character data. A text file can be thought of as a stream of characters that can be processed sequentially.
unformatted data filesorganizes data into blocks containing contiguous bytes of information. These blocks represent more complex data structures, such as arrays and structures.
System-oriented data files are more closely related to the computers operating
File
Text files
Binary files
File operations
Different operations that can be performed on a file are Creation of a new file Opening an existing file Reading from a file Writing to a file Closing a file
opening a file
A data file must be opened before it can be created or processed. To open the file we have called the function fopen( ). The general format of opening a file is fp=fopen(filename,mode); filename-string of characters that makeup a valid filename for the os. mode specifies the purpose of opening the file.
example
FILE *FP; FP=FOPEN(sample.dat,w); will open a new data file called sample.dat as writing only mode
Closing a file
A data file must be closed as soon as all the operations on it
have been completed. A library function fclose is for this purpose Syntax is fclose(file-pointer) Ex:fclose(fp);
are there. Function purpose name getc() Putc() getw putw fprintf fscanf fgets fputs read a character from file write a character to file read integer write integer write set of data values read set of data values Read string of characters from file Write string of characters to file
getc is used to read a character from a file that has been opened
putc(c,fp); will write the character contained in character variable c to the file associated with FILE pointer fp.
putw(integer,fp); getw(fp);
Program #include <stdio.h> main() { FILE *f1, *f2, *f3; int number, i; f1 = fopen("DATA", "w"); for(i = 1; i <= 30; i++) { scanf("%d", &number); if(number == -1) break; putw(number,f1); } fclose(f1); f1 = fopen("DATA", "r"); f2 = fopen("ODD", "w"); f3 = fopen("EVEN", "w");
/* Read from DATA file */ while((number = getw(f1)) != EOF) { if(number %2 == 0) putw(number, f3); /* Write to EVEN file */ else putw(number, f2); /* Write to ODD file */ } fclose(f1); fclose(f2); fclose(f3); }
fp is a file pointer associated with a file that has been opened for
writing.
control string is file output specifications list may include variable, constant and string.
ex:fprintf(f1,%s %d,name,age);
Here name is an array variable of type char and age is an int variable
/* Writes records to a file using structurewhile ( another == 'Y' ) */ #include "stdio.h" { main( ) printf ( "\nEnter name, age and basic salary: " ) { ; FILE *fp ; scanf ( "%s %d %f", e.name, &e.age, &e.bs ) ; char another = 'Y' ; fprintf ( fp, "%s %d %f\n", e.name, e.age, e.bs struct emp ); { printf ( "Add another record (Y/N) " ) ; char name[40] ; fflush ( stdin ) ; int age ; another = getche( ) ; float bs ; } }; fclose ( fp ) ; struct emp e ; fp = fopen ( "EMPLOYEE.DAT", "w" ) ; fp = fopen ( "EMPLOYEE.DAT", "r" ) ; if ( fp == NULL ) if ( fp == NULL ) { { puts ( "Cannot open file" ) ; puts ( "Cannot open file" ) ; exit( ) ; exit( ) ; } } while ( fscanf ( fp, "%s %d %f", e.name, &e.age, &e.bs ) != EOF ) printf ( "\n%s %d %f", e.name, e.age, e.bs ) ; fclose ( fp ) ;
fputs() does not automatically add a new line character the end of the string, it must be explicitly done.
syntax
returns EOF.
Fgets function
Fgets() which reads in an entire line from file fgets ( string ,maxlen, fp );
Fgets function returns the same string parameter on success.If the End-of-File is encountered and no characters have been read, a null pointer is returned.
Example for fgets FILE *fptr; char line [1000]; /* Open file and check it is open */ while (fgets(line,1000,fptr) != NULL) { printf ("Read line %s\n",line);
Feof()
It is defined in <stdio.h> Prototype:int feof( FILE * ); Used to determine if the end of the file (stream) specified, has been
reached. Return Nonzero (true) if the end of file has been reached, zero (false) otherwise. Example: #include <stdio.h> int main(void) { char buffer[256]; FILE * myfile; myfile = fopen("some.txt","r"); while (!feof(myfile)) { fgets(buffer,256,myfile); printf("%s",buffer); } fclose(myfile); } This example opens a file called some.txt for reading, then in a loop, reads lines from the file and outputs them to the screen. The loop continues until the end of the file has come.
data.Each block will generally represent a complex data structure, such as a structure or an array. The library functions fread and fwrite are intended to be used in situations of this type. The function fwrite sends a block of data to the specified file. The function fread reads a block of data from file
Fwrite and fread function have 4 arguments The first argument is the address of the structure to be write to the disk/read from file. The second argument is the size of the structure in bytes.sizeof() operator gives the size of the variable in bytes. The third argument is the number of such structures that we want to read/write at one time. The last argument is the pointer to the file ,we want to read/write.
Example
fpt is the stream pointer associated with a data file that has been opened for output. fread(&customer,sizeof(record),1,fpt);
main( )
{ FILE *fp ; char another = 'Y' ; struct emp
{
char name[40] ; int age ; float bs ; }; struct emp e ; fp = fopen ( "EMP.DAT", "wb" ) ; if ( fp == NULL ) {
while ( another == 'Y' ) { printf ( "\nEnter name, age and basic salary: " ) ; scanf ( "%s %d %f", e.name, &e.age, &e.bs ) ; fwrite ( &e, sizeof ( e ), 1, fp ) ; printf ( "Add another record(Y/N)); another = getche( ) ; } fclose ( fp ) ; //reads records from file fp = fopen ( "EMP.DAT", "rb" ) ; if ( fp == NULL ) { puts ( "Cannot open file" ) ; exit( ) ; } while ( fread ( &e, sizeof ( e ), 1, fp ) == 1 ) printf ( "\n%s %d %f", e.name, e.age, e.bs ) ; fclose ( fp ) ; }
wb in fopen command Binary files can be processed sequentially or, depending on the needs of the application, they can (and usually are) processed using random access techniques Binary files differ from text files in two ways mainly: Handling of newlines: representation of end of file: storage of numbers:
3.
. If we want to access a particular record random access takes less time than the sequential access. Functions for Random access are rewind() return the file pointer to the beginning fseek() position the file pointer; ftell() return the current offset of the file pointer.
fseek
This function is used for setting the file position pointer at the
specified bytes
Three arguments are used by the fseek function:
from the formula: the desired record number * the size of one record
3. origin-Position from where offset is added. It is specified by one
value 0
description
Move the offset bytes from Beginning of file Move the offset bytes from Current position of the file pointer Move the offset bytes from End of file
/* fseek example */ #include <stdio.h> Void main () { FILE * pFile; pFile = fopen ( "example.txt" , "w" ); fputs ( "This is an apple." , pFile ); fseek ( pFile , 9 , SEEK_SET ); fputs ( " sam" , pFile ); fclose ( pFile ); } After this code is successfully executed, the file example.txt contains: This is a sample.
statement
fseek(fp,0L,0); fseek(fp,0L,2); fseek(fp,-m, 1); fseek(fp,m,0); fseek(fp,m,1); fseek(fp,-m,1); fseek(fp,-m,2)
meaning
Go to the begining Go to end of file move back by m bytes from current position move to (m+1)th byte in file Go forward by m bytes Go backward by m bytes from current position Go backward by m bytes from end
ftell
Prototype: long int ftell ( FILE * fp ); returns current byte position in file On success, the current value of the position indicator is returned.If an error occurs, -1L is returned,
/* ftell example : getting size of a file */ #include <stdio.h> int main () { FILE * pFile; long size; pFile = fopen ("myfile.txt","rb"); if (pFile==NULL) perror ("Error opening file"); else { fseek (pFile, 0, SEEK_END); size=ftell (pFile); This program prints out the size fclose (pFile); of myfile.txt in bytes. printf ("Size of myfile.txt: %ld bytes.\n",size); } }
rewind
Prototype:void rewind ( FILE * fp); Set position indicator to the beginning On streams open for update (read+write), a call to rewind allows
BITWISE OPERATIONS
Some applications require the manipulation of individual bits
within a word of memory C contains several special operators that allow such bitwise operations to be carried out easily and efficiently. These bitwise operators can be divided into three general categories: ones complement operator logical bitwise operators shift operators
the bits of its operand to be inverted EXAMPLE PROGRAM main ( ) { unsigned i = Ox5b3c; printf("hexadecima1values: i = %x ~i = %x\n", i, ~i); } OUTPUT hexadecimal values: i = 5b3c -i = a4c3 i = 0101 1011 0011 1100 -i = 1010 0100 1100 0011 (a4c3)
A bitwise and expression will return a 1 if both bits have a value of 1 (i.e., if both bits are true).Otherwise, it will return a value of 0. A bitwise exclusive or expression will return a 1 if one of the bits has a value of 1 and the other has a value of 0 (one bit is true, the other false). Otherwise, it will return a value of 0. A bitwise or expression will return a 1 if one or more of the bits have a value of 1 (one or both bits are true). Otherwise, it will return a value of 0.
Example
a=Ox6db7 b= Oxa726 a b = = 0110 1101 1011 0111 1010 0111 0010 0110 = 0x2526
a & b = 0010 0101 0010 0110 a b = 0110 1101 1011 0111 = 1010 0111 0010 0110
a ^b = 1100 1010 1001 0001 a b a|b = 0110 1101 1011 0111 = 1010 0111 0010 0110 = 1110 1111 1011 0111
= Oxca91
= Oxefb7
Masking
Masking is a process in which a given bit pattern
is transformed into another bit pattern by means of a logical bitwise operation. The original bit pattern is one of the operands in the bitwise operation. The second operand, called the mask, is a specially selected bit pattern that brings about the desired transformation.
a is an unsigned integer variable whose value is Ox6db7. b = a & Ox3f; The second operand (the hexadecimal constant Ox3f) will serve as a mask. Thus, the resulting value of b will be 0x37. a = 0110 1101 1011 0111 mask = 0000 0000 0011 1111 b = 0000 0000 0011 0111 = 0x37.
Shift Operators
The two bitwise shift operators are
shift left (<<) shift right (>>) Each operator requires two operands. The first is an integer-type operand that represents the bit pattern to be
0s.
a=Ox6db7 b = a << 6;
Shift right
The right shift operator causes all of the bits in the first operand
to be shifted to the right by the number of positions indicated by the second operand.
The rightmost bits (i.e., the underflow bits) in the original bit
a=Ox6db7 b = a >> 6;
operators. &= ^= |= <<= >>= The left operand must be an assignable integertype identifier and the right operand must be a bitwise expression. For example a &= Ox7f is equivalent to a = a & Ox7f.
Bitfields
C allows integer members to be stored into memory spaces smaller than the compiler would ordinarily allow. These spacesaving structure members are called bit fields, and their width in bits can be explicitly declared. General format is: Struct bitfield_tag struct sample { { unsigned a : 1; unsigned b : 3; Unsigned int member1:bit_width1; unsigned c : 2; Unsigned int member2:bit_width2; unsigned d : 1; }; .. struct sample v; Unsigned int memberN:bit_widthn; }
Bitfields Enable better memory utilization Members Must be declared as int or unsigned
Enumeration
An enumeration is a user defined data type, similar to a structure or a
union.
General format to declare enumeration type is
declaration
Enumeration constants (members)are automatically assigned equivalent integer values, beginning with 0 for the first member , with each successive members has value increased by 1. Ex: enum days{mon,tue,wed,thur,fri,sat,sun}; Enum days start,end; Here mon to sun will assigned the values 0 to 6 Enumeration constants can be assigned explicit integer values which differ from the default values.
Those constants that are not assigned explicit values will automatically be assigned
values which increase successively by 1 from the last explicit assignment. For ex:enum colors {black = -1, blue, cyan, green, magenta, red = 2, white, yellow); Values will be
Advantage of enumeration
The first advantage is that enumerated constants are generated
automatically by the compiler. Conversely, symbolic constants must be manually assigned values by the programmer. Another advantage of using the enumeration constant method is that your programs are more readable
termination successful or not When main is called, it is called with two arguments. The first argc, for argument count is the number of command-line
#include <stdio.h> main ( int argc, char *argv[ ] ) { FILE *fs, *ft ; char ch ; if ( argc != 3 ) { puts ( "Improper number of arguments" ) ; exit( ) ; } fs = fopen ( argv[1], "r" ) ; if ( fs == NULL ) { puts ( "Cannot open source file" ) ; exit( ) ; }
ft = fopen ( argv[2], "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 ) ; }
MACROS
A macro is a fragment of code which has been given a name. Whenever
Example program for macro #include <stdio.h> #define area length * width main( ) { int length,width; printf("length =) ; scanf('%d", &length); printf ("width = " ) ; scanf ("%d, &width); printf( " \n area = %d", area); }
replacement text, when the macro is expanded General form is #define identifier(f1,f2,fn) string Identifier F1,f2,.fn are formal macro arguments.when macro called preprocessor substitutes the string
Ex: #define AREACIRCLE ( x ) ( PI * ( x ) * ( x ) ) When the statement area = AREACIRCLE( 4 ); executed then macro expand to 3.14*4*4.
2.
3.
4.
5.
macros make the program run faster but increase the program size, whereas functions make the program smaller and compact. When passing arguments to a macro, the number of arguments will be checked, but their data types will not. Thus, there is less error checking than with a function call. A macro identifier is not associated with an address,a macro identifier cannot be passed to a function as an argument, in the same sense that a function can be passed to another function as an argument . macro cannot call itself recursively .function can call recursively Macro cannt return value.function can return value
C preprocessor
The C preprocessor is a program that processes
unconditional
conditional
pragma define undef include line error if else elif ifdef ifndef endif
Explanation Defines a macro Undefines a macro Textually includes content of file Makes compilation of code conditional on macro being defined
#ifndef
#endif #if
#else
#elif #line #error #pragma
#undef
The #undef directive undefines a symbolic constant or a macro
identifier; i.e., it negates the effect of a #define directive that may have appeared earlier in the program. If a symbolic constant or macro has been undefined it can later be redefined General form is #undef macroname #define FOREGROUND 7 main ( ) { ..... #undef FOREGROUND ..... }
#include
The #include has 2 general forms #include <filename> and #include "filename"
Inserts the entire contents of filename in place of the #include line. First form is used for standard library header file. Angle brackets<>
indicates search for header file in standard location of library definitions. Second form Searches for a file in current directory.it is used for programmer-defined header files
Conditional Compilation
Enable the programmer to control the execution of preprocessor
integer expression.
Cast expressions, sizeof()expressions, and enumeration constants cannot
structure.
These directives are very helpful in testing and debugging some part of C
program
#ifdef
#ifdef allows a section of a program to be compiled only if the
macro that is specified as the parameter has been defined, no matter which its value is.
General form is
#endif
independently of its value. If it was not defined, that line will not be
included in the program compilation.
#ifndef
#ifndef serves for the exact opposite: the code
#ifndef TABLE_SIZE
condition to be met in order for the portion of code they surround to be compiled.
The condition that follows #if or #elif can only evaluate constant
#endif
#else
<statement sequence2> #endif
Ex: #if TABLE_SIZE>200 #undef TABLE_SIZE #define TABLE_SIZE 200 endif The #elif command is similar to #if, except that it is used to extract one from a series of blocks of code.
if TABLE_SIZE>200 #undef TABLE_SIZE #define TABLE_SIZE 200 #elif TABLE_SIZE<50 #undef TABLE_SIZE #define TABLE_SIZE 50 #else #undef TABLE_SIZE #define TABLE_SIZE 100 #endif
#
int table[TABLE_SIZE];
or #ifndef.
#error
The directive #error causes the preprocessor to report a fatal
error.
General form is
#error error-message
It will Stops preprocessing and prevents program compilation
#pragma
This directive is another special-purpose directive that you can
depend on compiler
May use compiler-specific options Unrecognized #pragmas are ignored
#line
#line directive is used to change value of the LINE- and FILE-
variables
Filename is optional General form is
file1.Cpp
Advantages of Preprocessor in C
It improves the readability of C program.
Description
The line number of the current source code line (an integer constant). The presumed name of the source file (a string). The date the source file is compiled (a string of the form "Mmm dd yyyy" such as "Jan 19 2001"). The time the source file is compiled (a string literal of the form "hh:mm:ss").
#define PRINT_INT(x) printf(#x " = %d\n", x) PRINT_INT(i/j); The preprocessor will replace the call of PRINT_INT by the following code: printf("i/j" " = %d\n", i/j); which is equivalent to printf("i/j = %d\n", i/j);
## operator ## by itself is known as the token-pasting operator Concatenates two tokens Ex: #define TOKENCONCAT( x, y ) x ## y TOKENCONCAT( O, K ) becomes OK
During program development, programmers often find it helpful to comment out large portions of code to prevent it from being compiled
For giving comments we can use #if 0 code prevented from compiling... #endif