You are on page 1of 79

Pakistan Navy Engineering College / National University of Sciences & Technology

Object Oriented Programming CS-212 Lab Manual


(December 2012)

Prepared by Engr. Sajid Saleem Assistant Professor EPE Department

UNIFIED CURRICULA 2012

Object Oriented Programming CS-212


(December 2012)

List Of Practicals S No 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Practicals Practice of Computer Fundamental Concepts Preprocessor Arrays and Vectors Pointers and Pointer-based strings Stream Input / Output Class String and String Stream Processing Bits, Characters, C-Strings and structs Classes: A Deeper Look Operator Overloading: String and array Objects OOP: Inheritance OOP: Polymorphism Templates and Exception Handling File Processing Week 1 2 3,4 5 6 7 8 9 10,11 12 13 14 15

LAB # 1 PRACTICE OF COMPUTER FUNDAMENTAL CONCEPTS

LAB OBJECTIVE
A quick review of the fundamental programming concepts of C++

OVERVIEW
The first lab focuses on revising the basic concepts of C++ language as studied by the students previously. A recall is important as the programming skills being taught in this course need a thorough knowledge of fundamental techniques. Following is a comprehensive code provided for reviewing previous knowledge and to help in clearing relevant ambiguities. The code has to be run and understood for further modifications in it.

//lab1a.cpp // revising basic concepts using an example of a calculator #include<iostream>// allows program to output data to the screen using std::cout; //program uses cout using std::cin; //program uses cin using std::endl; //program uses endl class calc { public: //class definition //public access specifier

int add(int a, int b) //functions for implementing calcultor operations { c=a+b; return c; } int sub(int a, int b) {

c=a-b; return c; } int mult(int a, int b) { c=a*b; return c; } void div(int a, int b) { int d=a/b; cout<<"\nQuotient: "<< d <<"\t\tRemainder: "<<remainder(a,b)<<"\n\n"; //function div can access a private fuction } private: //private members only accessible by functions of the class and not by functions outside the class (like main) int c; int remainder(int a, int b) { c=a%b; return c; } }; //end of class calc int factorial (int a); //function prototype int main() //fuction of main starts { calc myCalc; //object of class calc named myCalc, it can have any name int x,y; char choice; cout<<"THIS IS A SIMPLE CALCULATOR\n\n"; //printing text on screen cout<<"Enter choice of operation\n + for addition\n - for subtraction\n * for multiplication\n / for division\n f for factorial\n"; cin>>choice; cout<<"\nEnter First Number: "; //prompting

cin>>x;

//and taking input from user

cout<<"\nEnter Second Number: "; cin>>y; //second input from user switch(choice) //conditional statement { case'+': cout<<"\nSum: "<<myCalc.add(x,y)<<"\n\n"; //function calling and printing text on screen break; case'-': cout<<"\nDiffernce: "<<myCalc.sub(x,y)<<"\n\n"; break; case'*': cout<<"\nProduct: "<<myCalc.mult(x,y)<<"\n\n"; break; case'/': myCalc.div(x,y); break; case'f': cout<<"\nFactorial of first number : "<<factorial(x)<<"\n\n"; cout<<"Factorial of second number : "<<factorial(y)<<"\n\n"; break; default: //exception handling cout<<"\ninvalid choice"; } return 0; // indicate successful termination } int factorial( int number ) //function definition { if ( number <= 1 ) // test for base case return 1; // base cases: 0! = 1 and 1! = 1 else// recursion step return number * factorial( number - 1 ); } // end of factorial function

The above program implements the operation of a simple calculator using the following features of C++ programming:Classes and objects, multi-function, recursion and conditional statements. The mathematical operations are implemented using multi-functions. The functions for addition, subtraction, multiplication and division are defined as public members of the classcalc, hence they can be accessed by functions outside the class (like main). The function for calculating remainder after dividing the numbers is a private member of the class and can only be accessed by the members of class. Similarly, the variable for holding the results is also a private member. The function for calculating factorial of numbers is not a part of class and is prototyped before the body of main starts. The logic of this function is based on recursion. The members of class cannot be accessed without an object, so firstly we create an object of the class calc named myCalc in the body of main function. The users of the program are given an option to choose the operation they want to be performed on the two numbers taken as input from the users. This is implemented in the program using the conditional statement switch. A particular function is executed according to the chosen operation. As we can see that remainder function is a part of division function and it displays both, the quotient and the remainder.

TASK(S)
1- Recode lab1a.cpp and implement the function of factorial by replacing the recursion with a loop. 2- Recode lab1a.cpp and replace the switch statement with if-else statements for using multi-functions.

LAB # 2 PREPROCESSORS

LAB OBJECTIVE
Learning the use of different preprocessor directives and creating macros for small functions.

OVERVIEW
Preprocessing occurs before a program is compiled. Some possible actions are inclusion of other files in the file being compiled, definition of symbolic constants and macros, conditional compilation of program code and conditional execution of preprocessor directives. All preprocessor directives begin with #, and only white-space characters may appear before a preprocessor directive on a line. Preprocessor directives are not C++ statements, so they do not end in a semicolon (;). Functions of some preprocessor directives are: 1. The #includedirective causes a copy of a specified file to be included in place of the directive. The two forms of the #include directive are: #include <filename> (including header file) #include "filename" (including header file created by the user)

2.

The #definepreprocessor directive creates symbolic constants,constants represented as symbols. When this line appears in a file, all subsequent occurrences (except those inside a string) of identifier in that file will be replaced by replacement-text before the program is compiled. For example: #definePI 3.14159

3.

Conditional compilation enables the programmer to control the execution of preprocessor directives and the compilation of program code. The conditional preprocessor construct is much like the if selection structure. For example: #ifndefNULL #define NULL 0 #endif

Every #if construct ends with #endif. A multiple-part conditional preprocessor construct may be tested using the #elif (the equivalent of else if in an if structure) and the #else (the equivalent of else in an if structure) directives. #ifdef and #undef are also used in conditional compilation.

Here are two codes that manipulate preprocessor directives:

//lab2a.cpp //use of macros #include<iostream> #include<stdio.h> #include<conio.h> using std::cin; using std::cout; using std::endl; #define SQUARE(X) (X)*(X) //macro to calculate square of a number #define PR(X) cout<<"The result is: "<<X<<"\n"<<endl; //macro for printing result on screen int main(void) { int x = 4; int z; z = SQUARE(x); //z is equal of square of 4 PR(z); z = SQUARE(2); //z is equal of square of 2 PR(z); PR(SQUARE(x+2)); //calculating and printing result without storing result in z PR(100/SQUARE(2)); cout<<"x is "<<x<<"\n"<<endl; PR(SQUARE(++x)); cout<<"After incrementing, x is: "<<x<<"\n"<<endl; getch(); return 0; } The above code is a simple program which shows the use of macros in programming. Macros can replace simple functions as shown in the given example: #define SQUARE(X) (X)*(X)

It calculates the square of any number placed in place of X, by replacing SQUARE(X) with (X)*(X) wherever it is used.

//lab2b.cpp //use of conditional compilation and ## operator #include<iostream> #include<stdio.h>//including header files #include<conio.h> #define JUST_CHECKING //preprocessor directives #define LIMIT 4 #define TEXT 1 #define BOOK 2 #define WORK 3 #define HOME 4 #define TEXTBOOK 5 #define WORKBOOK 6 #define HOMEWORK 7 #define CAT(x,y) x##y //macro for concatenation (use of ## operator) using std::cout; //program uses cout using std::endl; //program used endl int main(void) { int i; int total = 0; for (i = 1; i <= LIMIT; i++) { total += 2*i*i + 1; #ifdef JUST_CHECKING //conditional compilation cout<<"i="<<i<<"\trunning total = "<<total<<"\n"<<endl; #endif } cout<<"Grand total = "<<total<<"\n"<<endl; cout<<"Now let's try concatenation\n"<<endl;

cout<<CAT(TEXT,BOOK)<<"\n"<<endl; //using macro for concatenation cout<<CAT(HOME,WORK)<<"\n"<<endl; cout<<CAT(WORK,BOOK)<<"\n"<<endl; cout<<CAT("WORK","BOOK")<<"\n"<<endl; getch(); return 0; // indicate successful termination } Here is another code that is helpful in understanding conditional compilation. JUST_CHECKING is defined in the beginning and the program checks if it is defined or not and on the basis of that it executes the given instructions. It also shows the use of concatenation operator ##.The ## operator must have at least two operands as it combines the tokens.

TASK(S)
1- Use macros to create a calculator. 2- Recode the program made for task 1 to insert macros for calculating area of a rectangle and a circle. 3 Recode the program made in task 2 to insert macros that indicates the maximum and minimum number, also to indicate if the numbers are equal.

LAB # 3 ARRAYS AND VECTORS

LAB OBJECTIVE
Manipulating arrays to process grouped data and understanding the use of library class template vector.

OVERVIEW
An array is a consecutive group of memory locations that all have the same type. The programmer specifies the type of the elements and the number of elements required by an array as follows: typearrayName [ arraySize ]; where the arraySize must be an integer constant greater than zero. To refer to a particular location or element in the array, we specify the name of the array and the position number of the particular element in the array. For example: if the name of the entire array is c and contains 5 elements then the elements of array c are referred to as c[0], c[1], c[2], c[3] andc[4]. Class template vector represents a more robust type of array featuring many additional capabilities. Vectorsuse template notation. It is defined in header <vector> and belongs to namespace std. The following codes give a clear idea of the different ways of using arrays and vectors in programming. // lab3a.cpp //storing values in an array and printing them #include<iostream> using std::cout; using std::endl; using std::cin; #include<iomanip> using std::setw; int main()

{ int n[ 10 ]; // n is an array of 10 integers // initialize elements of array n to 0 for ( int i = 0; i < 10; i++ ) { cout<<"Enter element number "<<i<<endl; //taking user input cin>>n[ i ]; //storing the value in array } cout <<"\nElement"<< setw( 13 ) <<"Value"<< endl; // output each array element's value for ( int j = 0; j < 10; j++ ) cout << setw( 7 ) << j << setw( 13 ) << n[ j ] << endl; return 0; // indicates successful termination } // end main

The above code is simple program that uses an array named nhaving 10 elements. For loop is used to assign values to its members as taken input from the user. Another for loop is used to print those values.

//lab3b.cpp // Passing arrays and individual array elements to functions. #include<iostream> using std::cout; using std::endl; #include<iomanip> using std::setw; void modifyArray( int [], int ); // function having the first argument as an array void modifyElement( int ); int main() { constint arraySize = 5; // size of array a int a[ arraySize ] = { 0, 1, 2, 3, 4 }; // initializing array a

cout <<"Effects of passing entire array by reference:" <<"\n\nThe values of the original array are:\n"; for ( int i = 0; i < arraySize; i++ ) cout << setw( 3 ) << a[ i ]; //displaying original array elements cout << endl; modifyArray( a, arraySize ); // passing array a to modifyArray by reference cout <<"The values of the modified array are:\n"; for ( int j = 0; j < arraySize; j++ ) cout << setw( 3 ) << a[ j ]; // displaying modified array elements cout <<"\n\n\nEffects of passing array element by value:" <<"\n\na[3] before modifyElement: "<< a[ 3 ] << endl; modifyElement( a[ 3 ] ); // passing array element a[ 3 ] by value cout <<"a[3] after modifyElement: "<< a[ 3 ] << endl; return 0; // indicates successful termination } // end main // in function modifyArray, "b" points to the original array "a" in memory void modifyArray( int b[], int sizeOfArray ) { for ( int k = 0; k < sizeOfArray; k++ ) b[ k ] *= 2; // multiplying each array element by 2 } // end of unction modifyArray // in function modifyElement, "e" is a local copy of array element a[ 3 ] passed from main void modifyElement( int e ) { cout <<"Value of element in modifyElement: "<< ( e *= 2 ) << endl; // multiply parameter by 2 }// end of function modifyElement

Passing an array to a function is an important array operation. When passing an array to a function, the array size is normally passed as well, so the function can process the specific number of elements in the array. C++ passes arrays to functions by reference; the value of the name of the array is the address in the computer's memory of the first element of the array. Because the starting address of the array is passed, the called function knows precisely where the array is stored in memory. Therefore, when the called function modifies array elements in its function body, it is modifying the actual elements of the array in their original memory locations. Individual array elements are passed by value exactly as simple variables are. The above program shows how a function having an array as an argument is declared,called and defined. In the function modifyArray, the whole array is processed and all the elements are multiplied by 2. Whereas,the function modifyElement has only one integer type argument to pass the value of any individual member of the array. In this code the 4th element of the array is passed and is multiplied by 2. In both the functions the actual values of the array elements are modified.

// lab3c.cpp // Linear search of an array. #include<iostream> using std::cout; using std::cin; using std::endl; int linearSearch( constint [], int, int ); //function prototype int main() { constint arraySize = 100; // size of array a int a[ arraySize ]; // creating array a int searchKey; // value to be located in array a for ( int i = 0; i < arraySize; i++ ) a[ i ] = 2 * i; // inserting data in the array cout <<"Enter integer search key: "; cin >> searchKey; // number to be searched in array taken as input int element = linearSearch( a, searchKey, arraySize ); // attempt to locate searchKey in array a // display results if ( element != -1 )

cout <<"Found value in element "<< element << endl; else cout <<"Value not found"<< endl; return 0; // indicates successful termination } // end main

int linearSearch( constintarray[], int key, int sizeOfArray ) // function compares key to every element of array until location is // found or until end of array is reached; { for ( int j = 0; j < sizeOfArray; j++ ) if ( array[ j ] == key ) // if found, return j; // return location of key return -1; // key not found } // end function linearSearch

Sometimes when dealing with a large amount of data it may be necessary to determine whether an array contains a value that matches a certain key value. The process of finding a particular element of an array is called searching. The above program compares each element of an array with a search key and displays the results accordingly. The linear searching method works well for small arrays or for unsorted arrays (i.e., arrays whose elements are in no particular order).

// lab3d.cpp // Demonstrating C++ Standard Library class template vector. #include<iostream> using std::cout; using std::cin; using std::endl; #include<iomanip>//declares the parameterized stream manipulators. using std::setw; #include<vector> using std::vector; void outputVector( const vector<int>& ); // display the vector

void inputVector( vector<int>& ); // input values into the vector int main() { vector<int> integers1( 7 ); // 7-element vector< int > vector<int> integers2( 10 ); // 10-element vector< int > // print integers1 size and contents cout <<"Size of vector integers1 is "<< integers1.size() <<"\nvector after initialization:"<< endl; outputVector( integers1 ); // print integers2 size and contents cout <<"\nSize of vector integers2 is "<< integers2.size() <<"\nvector after initialization:"<< endl; outputVector( integers2 ); // input and print integers1 and integers2 cout <<"\nEnter 17 integers:"<< endl; inputVector( integers1 ); inputVector( integers2 ); cout <<"\nAfter input, the vectors contain:\n" <<"integers1:"<< endl; outputVector( integers1 ); cout <<"integers2:"<< endl; outputVector( integers2 ); // use inequality (!=) operator with vector objects cout <<"\nEvaluating: integers1 != integers2"<< endl; if ( integers1 != integers2 ) cout <<"integers1 and integers2 are not equal"<< endl; // create vector integers3 using integers1 as an // initializer; print size and contents vector<int> integers3( integers1 ); // copy constructor cout <<"\nSize of vector integers3 is "<< integers3.size() <<"\nvector after initialization:"<< endl; outputVector( integers3 ); // use overloaded assignment (=) operator cout <<"\nAssigning integers2 to integers1:"<< endl; integers1 = integers2; // integers1 is larger than integers2

cout <<"integers1:"<< endl; outputVector( integers1 ); cout <<"integers2:"<< endl; outputVector( integers2 ); // use equality (==) operator with vector objects cout <<"\nEvaluating: integers1 == integers2"<< endl; if ( integers1 == integers2 ) cout <<"integers1 and integers2 are equal"<< endl; // use square brackets to create rvalue cout <<"\nintegers1[5] is "<< integers1[ 5 ]; // use square brackets to create lvalue cout <<"\n\nAssigning 1000 to integers1[5]"<< endl; integers1[ 5 ] = 1000; cout <<"integers1:"<< endl; outputVector( integers1 ); // attempt to use out-of-range subscript // cout << "\nAttempt to assign 1000 to integers1.at( 15 )" << endl; // integers1.at( 15 ) = 1000; // ERROR: out of range return 0; } // end main

// output vector contents void outputVector( const vector<int>&array ) { size_t i; // declare control variable for ( i = 0; i <array.size(); i++ ) { cout << setw( 12 ) <<array[ i ]; if ( ( i + 1 ) % 4 == 0 ) // 4 numbers per row of output cout << endl; } // end for if ( i % 4 != 0 ) cout << endl; } // end function outputVector

// input vector contents void inputVector( vector<int>&array ) { for ( size_t i = 0; i <array.size(); i++ ) cin >>array[ i ]; } // end function inputVector

The above code is based on the use of vectors. Two vector objects are created that store values of type int.integers1 contains seven elements, and integers2 contains 10 elements. By default, all the elements of each vector object are set to 0. Vectors can be defined to store any data type, by replacing int in vector<int> with the appropriate data type. Two functions inputVector and outputVector are used in this code for assigning values to the elements and printing the values respectively. Square brackets ([]) can be used to obtain a vector element. The size of a vector is built-in;every vector object "knows" its own size, which can be obtained by invoking the vector object's size member function).Thus, when we pass a vectorobject into a function, we will not have to pass the size of the vector as an argument. Member function size of class template vector returns the number of elements in a vector as a value of type size_t(which represents the type unsigned int on many systems). In the program, the control variable iis to be of type size_t. On some compilers, declaring i as an int causes the compiler to issue a warning message, since the loop-continuation condition would compare a signed value (i.e., inti) and an unsigned value (i.e., a value of type size_t returned by function size). Another point to note is that in the program an error has been mentioned as comments. Since vector object integers1 has seven elements so trying to access the 15th element would cause a run time error.

TASK(S):
1- Recode lab3a.cpp to add two arrays to input float values and characters from user and displaying values of array element on screen. 2- Recode lab3b.cpp and by passing the given array to function, add a function that indicates the prime numbers. 3- Recode lab3c.cpp to add an array having 10 elements whose values are based on user input and sort the values in ascending and descending order.

LAB # 4 POINTERS AND POINTER-BASED STRINGS


LAB OBJECTIVE
Manipulating pointers for different data types.

OVERVIEW
A pointer variable contains the memory address of a variable that, in turn, contains a specific value. In this sense a pointer indirectly references a value. Each variable being declared as a pointer must be preceded by an asterisk (*). For example, the declaration double *xPtr, *yPtr; indicates that both xPtr and yPtr are pointers to double values. Pointers can be declared to point to objects of any data type. The statement: yPtr = &y; assigns the address of the variable y to pointer variable yPtr. Then variable yPtr is said to "point to" y. The * operator, commonly referred to as the indirection operator or dereferencing operator, returns the value of the variable the pointer points to. If y=5 then *yptr would return the value of y that is 5. Arrays and pointers are intimately related in C++ and may be used almost interchangeably. An array name can be thought of as a constant pointer. Pointers can be used to do any operation involving array subscripting. The following codes will clarify the use of pointers.

//lab4a.cpp // Using subscripts and pointer notations with arrays. #include<iostream> using std::cout; using std::endl;

int main() { int b[] = { 10, 20, 30, 40 }; // create 4-element array b int *bPtr = b; // set bPtr to point to array b cout <<"Array b printed with:\n\nArray subscript notation\n"; for ( int i = 0; i < 4; i++ ) cout <<"b["<< i <<"] = "<< b[ i ] <<'\n'; // output array b using array subscript notation

cout <<"\nPointer/offset notation where "<<"the pointer is the array name\n"; for ( int offset1 = 0; offset1 < 4; offset1++ ) cout <<"*(b + "<< offset1 <<") = "<< *( b + offset1 ) <<'\n'; // output array b using the array name and pointer/offset notation cout <<"\nPointer subscript notation\n"; for ( int j = 0; j < 4; j++ ) cout <<"bPtr["<< j <<"] = "<< bPtr[ j ] <<'\n';// output array b using bPtr and array subscript notation cout <<"\nPointer/offset notation\n"; for ( int offset2 = 0; offset2 < 4; offset2++ ) cout <<"*(bPtr + "<< offset2 <<") = "<< *( bPtr + offset2 ) <<'\n'; // output array b using bPtr and pointer/offset notation } // end main

The first code shows the relationship between arrays and pointers. Pointers can be used to do any operation involving array subscripting. As we know that the array name (without a subscript) is a pointer to the first element of the array so bPtr is set to the address of the first element in array bby declaring bPtr = b; which is equivalent to bPtr = &b[ 0 ];

Array element b[ x ] (x is the subscript for any element in an array) can alternatively be referenced with the pointer expression *( bPtr + x ). The x in the preceding expression is the offset to the pointer, which is identical to the array subscript. Just as the array element can be referenced with a pointer expression, the address &b[ x ] can be written with the pointer expression (bPtr + x).

// lab4b.cpp // Cube a variable using pass-by-reference with a pointer argument. #include<iostream> using std::cout; using std::endl; void cubeByReference( int * ); // function prototype int main() { int number = 5; cout <<"The original value of number is "<< number; cubeByReference( &number ); // passing number address to cubeByReference cout <<"\nThe new value of number is "<< number <<"\n"<< endl; return 0; // indicates successful termination } // end main void cubeByReference( int *nPtr ) // function calculates cube of *nPtr; modifies variable number in main { *nPtr = *nPtr * *nPtr * *nPtr; // cube *nPtr } // end function cubeByReference

The above code shows how pointers can be used as arguments for functions. The address of a variable is passed to a function and the indirection operator (*) can be used in the function to form a synonym for the name of the variable in order to manipulate the value of the variable at that location in the caller's memory.

In this program the address of number is passed to the function. Function cubeByReference specifies parameter nPtr (a pointer to int) to receive its argument. The function dereferences the pointer and cubes the value to which nPtrpoint . This directly changes the value of number in main.

//lab4c.cpp //using pointer for string #include<iostream> using std::cin; using std::cout; using std::endl; void main() { char arr1[15]={"HAPPY BIRTHDAY"}; char *arr2[]={"HELLO","WORLD"};//two dimensional array char *arrptr1;//declaring character int i,j; arrptr1=arr1;//pointer to arr1 cout<<"\nPrinting first array using pointer notation: "; for(i=0;i<=14;i++) { cout<<*(arrptr1+i); } cout<<"\nPrinting first array using array notation: "; for(i=0;i<=14;i++) { cout<<arr1[i]; }

cout<<"\nPrinting second string using pointer notation: ";

for(i=0;i<=1;i++) { cout<<*(arr2+i)<<" "; } cout<<"\nPrinting second string using array notation: "; for(i=0;i<=1;i++) { cout<<arr2[i]<<" "; } cout<<"\nPrinting second array using 2D array notation: "; for(i=0;i<=1;i++) { for(j=0;j<=5;j++) { cout<<arr2[i][j]; } } cout<<endl; } The above program shows how pointers can be manipulated for string data. It also demonstrates the use of two dimensional character array or strings and the way of accessing their members using pointer and array notations.

TASK(S)
1- Recode lab4b.cpp to add a function that displays prime numbers between the two integers provided by the user. The function should have pointer arguments. 2- Recode task-1 to add a function that sorts those prime numbers in descending order. 3- Recode task-2 to add a function that calculates the factorial of the numbers between the two integers provided by the user.

4- Recode lab4c.cpp to take three string inputs in a two dimensional array of 3 rows and 15 columns and write a function that prints them.

LAB # 5 STREAM INPUT/OUTPUT

LAB OBJECTIVE
Understanding stream I/O operations and stream manipulation techniques.

OVERVIEW
C++ I/O occurs in streams, which are sequences of bytes. The bytes could represent characters, raw data, graphics images, digital speech, digital video or any other information an application may require. The system I/O mechanisms should transfer bytes from devices to memory (and vice versa). The C++ iostream library provides hundreds of I/O capabilities. The <iomanip> header declares services useful for performing formatted I/O with stream manipulators. Stream manipulators perform formatting tasks. They provide capabilities such as setting field widths, setting precision, setting and unsetting format state, setting the fill character in fields, flushing streams, inserting a newline or a null character into the output stream etc. The operation on I/O stream is shown in the following programs. // lab5a.cpp // Use of some stream manipulators #include<iostream> using std::cin; using std::cout; using std::dec; using std::endl; using std::hex; using std::oct; using std::fixed; using std::showbase; #include<iomanip> using std::setbase; using std::setprecision; #include<cmath> using std::sqrt;

void prec(void);//function prototype void showb(int);//function prototype int main() { int number; cout <<"Enter a decimal number: "; cin >> number; // input number // use hex stream manipulator to show hexadecimal number cout << number <<" in hexadecimal is: "<< hex << number << endl; // use oct stream manipulator to show octal number cout << dec << number <<" in octal is: " << oct << number << endl; // use setbase stream manipulator to show decimal number cout << setbase( 10 ) << number <<" in decimal is: " << number <<"\n\n"<< endl; showb(number); //function call prec();// function call return 0; } // end main void showb (int a) //displaying number with the respective base using stream manipulator showbase { cout <<"Printing number preceded by the base:"<< endl << showbase; cout <<"Decimal: "<< a << endl; // print decimal value cout <<"Hexadecimal: "<< hex << a << endl; // print hexadecimal value cout <<"Octal: "<< oct << a <<"\n\n"<< endl; // print octal value } //function end void prec(void) //funtion showing the use of stream manipulators setprecision and precision {

float root = sqrt(2.0); // calculating the value of square root of 2 int places; // precision, decimal places varying from 0-9 cout <<"value of square root of 2 with precisions 0-9."<< endl <<"Precision set by ios_base member function " <<"precision:"<< endl; cout << fixed; // use fixed-point notation // displaying root using ios_base function precision for ( places = 0; places <= 9; places++ ) { cout.precision( places ); cout << root << endl; } // end for cout <<"\nPrecision set by stream manipulator " <<"setprecision:"<< endl; // set precision for each digit, then display root for ( places = 0; places <= 9; places++ ) cout << setprecision( places ) << root << endl; } //function end

The above program uses stream manipulators hex, oct and dec to convert the number into different number systems. The function prec() shows the use of manipulators setprecision and precision, while the function showb() displays how showbase manipulator works. Some stream manipulators and their functions are as follows: Stream Manipulator skipws left right internal Description Skip white-space characters on an input stream. This setting is reset with stream manipulator noskipws. Left justify output in a field. Padding characters appear to the right if necessary. Right justify output in a field. Padding characters appear to the left if necessary. Indicate that a number's sign should be left justified in a field and a number's

Stream Manipulator

Description magnitude should be right justified in that same field (i.e., padding characters appear between the sign and the number).

dec oct hex showbase

Specify that integers should be treated as decimal (base 10) values. Specify that integers should be treated as octal (base 8) values. Specify that integers should be treated as hexadecimal (base 16) values. Specify that the base of a number is to be output ahead of the number (a leading 0 for octals; a leading 0x or 0X for hexadecimals). This setting is reset with stream manipulator noshowbase. Specify that floating-point numbers should be output with a decimal point. This is used normally with fixed to guarantee a certain number of digits to the right of the decimal point, even if they are zeros. This setting is reset with stream manipulator noshowpoint. Specify that uppercase letters (i.e., X and A tHRough F) should be used in a hexadecimal integer and that uppercase E should be used when representing a floating-point value in scientific notation. This setting is reset with stream manipulator nouppercase. Specify that positive numbers should be preceded by a plus sign (+). This setting is reset with stream manipulator noshowpos. Specify output of a floating-point value in scientific notation. Specify output of a floating-point value in fixed-point notation with a specific number of digits to the right of the decimal point.

showpoint

uppercase

showpos scientific fixed

//lab5b.cpp // Testing error states. #include<iostream> using std::cin; using std::cout; using std::endl; int main() { int integerValue; // display results of cin functions cout <<"Before a bad input operation:" <<"\ncin.rdstate(): "<< cin.rdstate() <<"\n cin.eof(): "<< cin.eof() <<"\n cin.fail(): "<< cin.fail() <<"\n cin.bad(): "<< cin.bad() <<"\n cin.good(): "<< cin.good() <<"\n\nExpects an integer, but enter a character: "; cin >> integerValue; // enter character value to have a bad input cout << endl; // display results of cin functions after bad input cout <<"After a bad input operation:" <<"\ncin.rdstate(): "<< cin.rdstate() <<"\n cin.eof(): "<< cin.eof() <<"\n cin.fail(): "<< cin.fail() <<"\n cin.bad(): "<< cin.bad() <<"\n cin.good(): "<< cin.good() << endl << endl; cin.clear(); // clear stream // display results of cin functions after clearing cin cout <<"After cin.clear()"<<"\ncin.fail(): "<< cin.fail() <<"\ncin.good(): "<< cin.good() << endl; return 0; } // end main

The clear member function is used to restore a stream's state to "good," (sets the goodbit) so that I/O may proceed on that stream.The state of a stream may be tested through bits in class ios_base. The rdstate member function returns the error state of the stream. A call to cout.rdstate, for example, would return the state of the stream, which then could be tested by a switch statement that examines eofbit, badbit, failbit and goodbit. The eofbit is set for an input stream after end-of-file is encountered. The failbit is set for a stream when a format error occurs on the stream, such as when the program is inputting integers and a nondigit character is encountered in the input stream. Thedata is not lost when this error occurs Thebadbit is set for a stream when an error occurs that results in the loss of data. The goodbit is set for a stream if none of the bits eofbit, failbit or badbit is set for the stream.

TASK(S)
1. Write a code which has two functions for adding and subtracting octal and hexadecimal numbers (numbers taken input from user in decimal form).

LAB # 6 CLASS STRING AND STRING STREAM PROCESSING

LAB OBJECTIVE
Learning various ways of manipulating strings and string processing.

OVERVIEW
To use strings, header file <string> is included. String can be initialized in multiple ways. Most string member functions take as arguments a starting subscript location and the number of characters on which to operate. Following codes demonstrate a few string manipulation techniques.

// lab6a.cpp // Demonstrating string assignment, concatenation, comparison and swapping #include<iostream> using std::cout; using std::endl; #include<string> using std::string; int main() { string string1( "cat" ); string string2; string string3; string2 = string1; // assign string1 to string2 string3.assign( string1 ); // assign string1 to string3 cout <<"string1: "<< string1 <<"\nstring2: "<< string2 <<"\nstring3: "<< string3 <<"\n\n"; int result = string1.compare( string2 ); //comparing string1 and string2 if ( result == 0 )

cout <<"string1.compare( string2 ) == 0\n\n"; else// result != 0 { if ( result > 0) cout <<"string1.compare( string2 ) > 0\n\n"; else// result < 0 cout <<"string1.compare( string2 ) < 0\n\n"; } // end else

// modify string2 and string3 string2[ 0 ] = string3[ 2 ] = 'r'; cout <<"After modification of string2 and string3:\n"<<"string1: " << string1 <<"\nstring2: "<< string2 <<"\nstring3: "; // demonstrating member function at for ( int i = 0; i < string3.length(); i++ ) cout << string3.at( i ); // declare string4 and string5 string string4( string1 + "apult" ); // concatenation string string5; // overloaded += string3 += "pet"; // create "carpet" string1.append( "acomb" ); // create "catacomb" // append subscript locations 4 through end of string1 to // create string "comb" (string5 was initially empty) string5.append( string1, 4, string1.length() - 4 ); cout <<"\n\nAfter concatenation:\nstring1: "<< string1 <<"\nstring2: "<< string2 <<"\nstring3: "<< string3 <<"\nstring4: "<< string4 <<"\nstring5: "<< string5 << endl;

// comparing string1 (elements 2-5) and string3 (elements 0-5) result = string1.compare( 2, 5, string3, 0, 5 ); if ( result == 0 ) cout <<"\nstring1.compare( 2, 5, string3, 0, 5 ) == 0\n"; else// result != 0 {

if ( result > 0 ) cout <<"\nstring1.compare( 2, 5, string3, 0, 5 ) > 0\n"; else// result < 0 cout <<"\nstring1.compare( 2, 5, string3, 0, 5 ) < 0\n"; } // end else //making a substring // begins at subscript 4 and consists of 4 elements cout <<"\nSubstring of string1: "<<string1.substr( 4, 4 ) <<"\n"<< endl; //string swapping string4.swap( string5 ); // swap string cout <<"\n\nAfter swapping:\nString4: "<< string4 <<"\nString5: "<< string5 << endl; return 0; } // end main The above code demonstrates string assignment, concatenation, comparison and swapping.String assignment has been done using = operator, as well as assign function. Member function assign copies a specified number of characters. Its format is: targetString.assign(sourceString, start, numberOfCharacters ); For concatenating addition assignment operator, += and member function appendhave been used. String member function compare has been used in different ways to compare strings. In the following line, result = string1.compare( string2 ); Variable result is assigned 0 if the strings are equivalent, a positive number if string1 is lexicographically (alphabetically) greater than string2 or a negative number if string1 is lexicographically less than string2. Similarly in result = string1.compare( 2, 5, string3, 0, 5 );the first two arguments (2 and 5) specify the starting subscript and length of the portion of string1 to compare with string3. The third argument is the comparison string. The last two arguments (0 and 5) are the starting subscript and length of the portion of the comparison string being compared. Member function substris used to retrieve a substring from a string. The first argument specifies the beginning subscript of the desired substring; the second argument specifies the substring's length. Class string provides member function swap for swapping strings.

//lab6b.cpp // Demonstrating the string find member functions, string erasing, replacement and insertion #include<iostream> using std::cout; using std::endl; #include<string> using std::string; int main() { string string1( "noon is 12 pm; midnight is not." ); int location; // find "is" at location 5 and 25 cout <<"Original string:\n"<< string1 <<"\n\n(find) \"is\" was found at: "<< string1.find( "is" ) <<"\n(rfind) \"is\" was found at: "<< string1.rfind( "is" ); // find 'o' at location 1 location = string1.find_first_of( "misop" ); cout <<"\n\n(find_first_of) found '"<< string1[ location ] <<"' from the group \"misop\" at: "<< location; // find 'o' at location 29 location = string1.find_last_of( "misop"); cout <<"\n\n(find_last_of) found '"<< string1[ location ] <<"' from the group \"misop\" at: "<< location; // find '1' at location 8 location = string1.find_first_not_of( "noi spm" ); cout <<"\n\n(find_first_not_of) '"<< string1[ location ] <<"' is not contained in \"noi spm\" and was found at:" << location; // find '.' at location 12 location = string1.find_first_not_of( "12noi spm" ); cout <<"\n\n(find_first_not_of) '"<< string1[ location ] <<"' is not contained in \"12noi spm\" and was " <<"found at:"<< location << endl; // search for characters not in string1 location = string1.find_first_not_of( "noon is 12 pm; midnight is not." );

cout <<"\nfind_first_not_of(\"noon is 12 pm; midnight is not.\")" <<" returned: "<< location << endl;

//string erasing string1.erase(13); // removes all characters from (and including) location 13 through the end of string1 cout<<"\nErasing a part of string: "<<string1<<endl;

//string replacement int position = string1.find( " " ); // find first space // replace all spaces with period while ( position != string::npos ) { string1.replace( position, 1, "." ); position = string1.find( " ", position + 1 ); } // end while cout <<"\n\nAfter replacement: "<<string1<<endl; //second repalcement position = string1.find( "." ); // find first period // replace all periods with two semicolons // NOTE: this will overwrite characters while ( position != string::npos ) { string1.replace( position, 2, "xxxxx;;yyy", 5, 2 ); position = string1.find( ".", position + 1 ); } // end while cout <<"After second replacement string1: "<< string1 << endl; //string insertion string string2( "beginning end" ); string string3( "middle " ); cout <<"\nString insertion\nInitial strings are:\nstring2: "<< string2 <<"\nstring3: "<< string3 <<"\n\n";

// insert "middle" at location 10 in string1 string2.insert( 10, string3 ); cout <<"Strings after insertion:\nstring2: "<< string2 <<"\nstring3: "<< string3 << endl; return(0); } // end main

The above code shows the use of string find member functions, string erasing, replacement and insertion. Member function rfind searchesstring1 backward (i.e., right-to-left). Member function find_first_of locates the first occurrence in string1 of any character in "misop". The searching is done from the beginning of string1. Member function find_last_of finds the last occurrence in string1 of any character in "misop". The searching is done from the end of string1. Member function find_first_not_of finds the first character in string1 not contained in "noispm". Searching is done from the beginning of string1. In the line,location = string1.find_first_not_of("noon is 12 pm; midnight is not." ); member function find_first_not_of finds the first character not contained in "noon is 12 pm; midnight is not." In this case, the string being searched contains every character specified in the string argument. Because a character was not found, string::npos (which has the value 1 in this case) is returned. string1.erase(13); removes all characters from (and including) location 13 through the end of string1. First replacement of the string is done by using find to locate each occurrence of the space character. Each space is then replaced with a period by a call to string member function replace. Function replace takes three arguments: the subscript of the character in the string at which replacement should begin, the number of characters to replace and the replacement string. And in the second repalcement every period and its following character is replaced with two semicolons. The member function insert can either have two or four arguments. Two arguments are used when an entire string is to be inserted. First argument is the location of the first string from

where insertion should begin and the second argument is the string to be inserted. When partial insertion of a string is needed we use four arguments, first is the location of the first string, second is the string to be copied and the last two arguments specify the starting and last element of string that should be inserted. Using string::npos causes the entire string to be inserted.

TASK(S):
1. 2. Write a code to take a string as input from user and create your own function for converting the string to uppercase alphabets. Recode task-1 to add another function that compares two strings. The functions for both the tasks should not include pre-defined functions for string manipulation.

LAB # 7 BIT, CHARACTER, C STRINGS AND STRUCT

LAB OBJECTIVE
Working on structures and various bitwise operators.

OVERVIEW This lab is based on structures and manipulation of individual bits of data.
Structures are like"superarray"ofaggregate data types,that is, they can be built using elements of several types. Structures are defined using the keyword struct followed by the structure name. Structure members can be variables of the fundamental data types (e.g., int, double, etc.) or aggregates, such as arrays, other structures and or classes and are placed within curly braces. Each structure definition must end with a semicolon. Structure definition does not reserve any space in memory; rather, it creates a new data type that is used to declare structure variables. Structure variables are declared like variables of other types. Structures or their individual members can also be passed in functions. You can access the individual elements of an array by using a subscript. Dot (.), the structure member operator is used is the following way: Structure variable.structure member C++ also provides extensive bit-manipulation capabilities for programmers who need to get down to the binary level. All data is represented internally by computers as sequences of bits. Each bit can assume the value 0 or the value 1 which are called binary numbers. The bitwise operators are: bitwise AND (&), bitwise inclusive OR (|), bitwise exclusive OR (^), left shift (<<), right shift (>>) and bitwise complement (~)also known as the one's complement. The following program demonstrates the use of structures.

//lab7a.cpp //Nested structure #include<iostream> using std::cin; using std::cout; #include<iomanip>

using std::setw; #define LEN 20 char * msgs[5] = { " Thank you for the wonderful evening, ", "You certainly prove that a ", "is a special kind of guy. We must get together", "over a delicious ", " and have a few laughs" }; struct names { // first template char first[LEN]; char last[LEN]; }; struct guy { // second template struct names handle; // nested structure char favfood[LEN]; char job[LEN]; float income; }; int main(void) { struct guy fellow = { { "Chip", "Vejer" }, "nachos plate", "memory broker", 36827.00 }; // initialize a variable cout<<"Dear "<< fellow.handle.first <<"\n\n"; cout<< msgs[0]<< fellow.handle.first <<"\n"; cout<< msgs[1] << fellow.job <<"\n"; cout<< msgs[2]<<"\n"; cout<< msgs[3] << fellow.favfood << msgs[4]; if (fellow.income > 150000.0) cout<<"!!"; elseif (fellow.income > 75000.0) cout<<"!"; else cout<<"."; cout<<"\n"<< setw(40)<<"See you soon,"; cout<<"\n"<<setw(34)<<"Shalala\n"; return 0; }

The above program is based on nested structures, which means a structure containing another structure. The template or structure definition of both the structures has been mentioned before the body of main.In this example the structure called names is nested within the one called guy. The guy structure contains the structure variable of type names called handle. The variable of guy type called fellow is declared and initialized in the body of main function and the structure members are printed along with the messages.

As we can see, the members of the structure names have to be accessed by using the dot operator twice, since it is nested within another structure. For instance,fellow.handle.first instructs the program to find fellow, then find the handle member of fellow, and then find the first member of handle.

// lab7b.cpp // Using the bitwise AND, bitwise inclusive OR, bitwise // exclusive OR, right shift and left shift operators. #include<iostream> using std::cout; using std::cin; using std::endl; int main() { int number1,number2, result; cout<<"Enter first number: "; //taking user input for numbers cin>>number1; cout<<"Enter second number: "; cin>>number2; // demonstrate & operator cout <<"\nUsing the bitwise AND operator &\n"; result=number1&number2; cout <<"number1&number2= "<<result<<"\n\n"<<endl; // demonstrate bitwise | cout <<"Using the bitwise OR operator |\n"; result=number1|number2; cout <<"number1|number2= "<<result<<"\n\n"<<endl; // demonstrate bitwise exclusive OR cout <<"Using the bitwise XOR operator ^\n"; result=number1^number2; cout <<"number1^number2= "<<result<<"\n\n"<<endl; // demonstrate bitwise right shift

cout <<"Using the bitwise right shift operator >>\n"; result=number1>>1; cout <<"Shifting first number one bit to right: number1>>1= "<<result<<"\n\n"<<endl; // demonstrate bitwise left shift cout <<"Using the bitwise left shift operator >>\n"; result=number2<<1; cout <<"Shifting second number one bit to left: number2<<1= "<<result<<"\n\n"<<endl; return 0; } // end main

The functions of the above used bitwise operators are: Operator Name
&

Description The bits in the result are set to 1 if the corresponding bits in the two operands are both 1. The bits in the result are set to 1 if one or both of the corresponding bits in the two operands is1. The bits in the result are set to 1 if exactly one of the corresponding bits in the two operands is 1. Shifts the bits of the first operand left by the number of bits specified by the second operand; fill from right with 0 bits. Shifts the bits of the first operand right by the number of bits specified by the second operand; the method of filling from the left is machine dependent. All 0 bits are set to 1 and all 1 bits are set to 0.

bitwise AND bitwise inclusive OR bitwise exclusive OR left shift right shift with sign extension bitwise complement

<<

>>

TASK(S):
1. 2. Recode lab7a.cpp to create an array of structure to input three records from the user and display them on screen. Recode lab7b.cpp to add a function that displays binary equivalent of decimal numbers.

LAB # 8 CLASSES: A DEEPER LOOK

LAB OBJECTIVE Covering advanced topics based on classes and objects. OVERVIEW
The lab focuses on the basic terms and concepts of C++ objectoriented programming which includes in-depth discussion on class, class scope and the relationships among members of a class. Constructors, destructors and friend functions are very commonly used with classes and are discussed in detail. Class members are immediately accessible by all of that class's member functions and can be referenced by name. Outside a class's scope, public class members are referenced through one of the handles on an object: an object name, a reference to an object or a pointer to an object. The dot member selection operator (.) is preceded by an object's name or with a reference to an object to access the object's members. The arrow member selection operator (->) is preceded by a pointer to an object to access the object's members. A constructor can be used to initialize an object of the class when the object is created. A constructor is a special member function that must be defined with the same name as the class, so that the compiler can distinguish it from the class's other member functions. An important difference between constructors and other functions is that constructors cannot return values and cannot specify a return type (not even void). Normally, constructors are declared public. A constructor that defaults all its arguments is also a default constructor i.e., a constructor that can be invoked with no arguments. There can be a maximum of one default constructor per class. A destructor is another type of special member function. The name of the destructor for a class is the tilde character (~) followed by the class name. A class's destructor is called implicitly when an object is destroyed. The destructor itself does not actually release the object's memory but it performs termination housekeeping before the system reclaims the object's memory, so the memory may be reused to hold new objects. A destructor receives no parameters and returns no value. Constructors and destructors are called implicitly by the compiler. The order in which these function calls occur depends on the order in which execution enters and leaves the scopes where the objects are instantiated. Generally, destructor calls are made in the reverse order of the corresponding constructor calls.

A friend function of a class is defined outside that class's scope, yet has the right to access the non-public (and public) members of the class. To declare a function as a friend of a class, precede the function prototype in the class definition with keyword friend. The following programs will help clearing the above mentioned concepts.

// lab8a.cpp // Demonstrating the class member access operators . and -> #include<iostream> using std::cout; using std::endl; // class Count definition class Count { public: void setX( int value ) // sets the value of private data member x { x = value; } // end function setX void print() { cout << x << endl; } // end function print private: int x; }; // end class Count int main() { Count counter; // creating counter object Count *counterPtr = &counter; // creating pointer to counter Count &counterRef = counter; // creating reference to counter cout <<"Set x to 1 and print using the object's name: "; counter.setX( 1 ); // setting data member x to 1 counter.print(); // calling member function print cout <<"Set x to 2 and print using a reference to an object: "; counterRef.setX( 2 ); // setting data member x to 2 counterRef.print(); // calling member function print cout <<"Set x to 3 and print using a pointer to an object: "; counterPtr->setX( 3 ); // setting data member x to 3 counterPtr->print(); // calling member function print return 0; // prints the value of private data member x

} // end main

This above mentioned code simply demonstrates the ways of accessing members of a class called Countthat has a private data member x of type int ,public member function setX and public member function print. The object for the class has been named counter and variable counterRef refers to counter, and variable counterPtr points to counter. Program can invoke member functions setX and print by using the dot (.) member selection operator preceded by either the name of the object (counter) or a reference to the object. Same can be done by using a pointer (countPtr) and the arrow (->) member selection operator. The following program which demonstrates the operation of constructors and destructors consists of three files: a header file and two .cpp files
//lab8b.h // Definition of class CreateAndDestroy. // Member functions defined in lab8b1.cpp. #include<string> using std::string; #ifndef CREATE_H #define CREATE_H class CreateAndDestroy { public: CreateAndDestroy( int, string ); // constructor ~CreateAndDestroy(); // destructor private: int objectID; // ID number for object string message; // message describing object }; // end class CreateAndDestroy #endif

// lab8b1.cpp // Member-function definitions for class CreateAndDestroy. #include<iostream> using std::cout; using std::endl; #include"lab8b.h"// include CreateAndDestroy class definition

CreateAndDestroy::CreateAndDestroy( int ID, string messageString ) constructor { objectID = ID; // setting object's ID number message = messageString; // set object's descriptive message cout <<"Object "<< objectID <<" constructor runs << message << endl; } // end CreateAndDestroy constructor CreateAndDestroy::~CreateAndDestroy() { cout << ( objectID == 1 || objectID == 6 ? "\n" : "" ); newline for certain objects; helps readability cout <<"Object "<< objectID <<" destructor runs << message << endl; } // end ~CreateAndDestroy destructor " // destructor "

//

// output

// lab8b2.cpp // Demonstrating the order in which constructors and destructors are called. #include<iostream> using std::cout; using std::endl; #include"lab8b.h"// include CreateAndDestroy class definition void create( void ); // prototype CreateAndDestroy first( 1, "(global before main)" ); // global object int main() { cout <<"\nMAIN FUNCTION: EXECUTION BEGINS"<< endl; CreateAndDestroy second( 2, "(local automatic in main)" ); static CreateAndDestroy third( 3, "(local static in main)" ); create(); // call function to create objects cout <<"\nMAIN FUNCTION: EXECUTION RESUMES"<< endl; CreateAndDestroy fourth( 4, "(local automatic in main)" ); cout <<"\nMAIN FUNCTION: EXECUTION ENDS"<< endl; return 0; } // end main // function to create objects void create( void ) {

cout <<"\nCREATE FUNCTION: EXECUTION BEGINS"<< endl; CreateAndDestroy fifth( 5, "(local automatic in create)" ); static CreateAndDestroy sixth( 6, "(local static in create)" ); CreateAndDestroy seventh( 7, "(local automatic in create)" ); cout <<"\nCREATE FUNCTION: EXECUTION ENDS"<< endl; } // end function create

The above mentioned program demonstrates the order in which constructors and destructors are called for objects of class CreateAndDestroyof various storage classes in several scopes. Each object of class CreateAndDestroy contains an integer (objectID) and a string (message)that are used in the program's output to identify the object. The destructor determines whether the object being destroyed has an objectID value 1 or 6 and, if so, outputs a newline character. The object first has global scope. Its constructor is actually called before any statements in main execute and its destructor is called at program termination after the destructors for all other objects have run. Function main declares three objects. Objects second and fourth are local automatic objects, and object third is a static local object. The constructor for each of these objects is called when execution reaches the point where that object is declared. The destructors for objects fourth and then second are called (i.e., the reverse of the order in which their constructors were called) when execution reaches the end of main. Because object third is static, it exists until program termination. The destructor for object third is called before the destructor for global object first, but after all other objects are destroyed. Function create declares three objects fifth and seventh as local automatic objects, and sixth as a static local object. The destructors for objects seventh and then fifth are called (i.e., the reverse of the order in which their constructors were called) when create terminates. Because sixth is static, it exists until program termination. The destructor for sixth is called before the destructors for third and first, but after all other objects are destroyed.

// lab8c.cpp // Friend functions #include<iostream> using std::cout; using std::endl; class Count // Count class definition { friendvoid setX( Count &, int ); // friend declaration public: Count() // constructor

: x( 0 ) // initialize x to 0 { // empty body } // end constructor Count void print() const// output x { cout << x << endl; } // end function print private: int x; // private member }; // end class Count void setX( Count &c, int val ) declared as a friend of Count { c.x = val; } // end function setX int main() { Count counter; // create Count object cout <<"counter.x after instantiation: "; counter.print(); setX( counter, 8 ); // set x using a friend function cout <<"counter.x after call to setX friend function: "; counter.print(); return 0; } // end main In this program function setX is a stand-alone function and not a member function of class Count. For this reason, when setX is invoked for object counter it passes counter as an argument to setX rather than using a handle (such as the name of the object) to call the function. And we can clearly see that the function setX can access the private member of the class. This is because the function is declared as the friend function of the class, had it not been so an error would have been generated. // function setX can modify private data of Count // because setX is

TASK(S): 1- Using constructor, destructor and friend functions, create a record for three employees that includes employee name, department, designation and salary.

LAB # 9 OPERATOR OVERLOADING: STRING AND ARRAY OBJECTS

LAB OBJECTIVE
Working on operator and function overloading.

OVERVIEW
Many common manipulations are performed with operators (e.g., input and output). Hence C++ enables operators to work with objects, and this process is called operator overloading. The jobs performed by overloaded operators can also be performed by explicit function calls, but operator notation is often clearer and more familiar to programmers. Programmers can use operators with user-defined types as well. Although C++ does not allow new operators to be created, it does allow most existing operators to be overloaded. One example of an overloaded operator built into C++ is <<, which is used both as the stream insertion operator and as the bitwise left-shift operator. Similarly, >> is also overloaded; it is used both as the stream extraction operator and as the bitwise right-shift operator. Operator is overloaded by writing a non-static member function definition or global function definition as you normally would, except that the function name now becomes the keyword operator followed by the symbol for the operator being overloaded. Operators that can be overloaded
+ ~ /= <<= -! %= == ->* * = / < % > ^ & | *= >>= ++ += -=

^= &= |= << >> != <= >= && || ,

-> [] () new delete

new[] delete[]

Operators that cannot be overloaded


. .* :: ?:

The precedence of an operator cannot be changed by overloading. However, parentheses can be used to force the order of evaluation of overloaded operators in an expression. Similarly, the associativity of an operator (i.e., whether the operator is applied right-to-left or left-to-right) cannot be changed by overloading. It is not possible to change the "arity" of an operator (i.e., the number of operands an operator takes): Overloaded unary operators remain unary operators; overloaded binary operators remain binary operators. C++'s only ternary operator (?:) cannot be overloaded. Operators &, *, + and - all have both unary and binary versions; these unary and binary versions can each be overloaded. Operator precedence and associativity chart is as follows. Operators are shown in decreasing order of precedence from top to bottom. Operator
:: :: () [] . -> ++ -typeid dynamic_cast< type > static_cast< type >

Type binary scope resolution unary scope resolution parentheses array subscript member selection via object member selection via pointer unary postfix increment unary postfix decrement runtime type information runtime type-checked cast compile-time type-checked cast

Associativity left to right

left to right

reinterpret_cast< type > cast for nonstandard conversions const_cast< type > ++ -+ ! ~ sizeof

cast away const-ness unary prefix increment unary prefix decrement unary plus unary minus unary logical negation unary bitwise complement determine size in bytes right to left

Operator
& * new new[] delete delete[] ( type ) .* ->* * / % + << >> < <= > >= == != & ^ | && ||

Type address dereference dynamic memory allocation dynamic array allocation dynamic memory deallocation dynamic array deallocation C-style unary cast pointer to member via object pointer to member via pointer multiplication division modulus addition subtraction bitwise left shift bitwise right shift relational less than relational less than or equal to relational greater than relational greater than or equal to relational is equal to relational is not equal to bitwise AND bitwise exclusive OR bitwise inclusive OR logical AND logical OR

Associativity

right to left left to right

left to right

left to right

left to right

left to right

left to right

left to right left to right left to right left to right left to right

Operator
?: = += -= *= /= %= &= ^= |= <<= >>= ,

Type ternary conditional assignment addition assignment subtraction assignment multiplication assignment division assignment modulus assignment bitwise AND assignment bitwise exclusive OR assignment bitwise inclusive OR assignment bitwise left-shift assignment bitwise right-shift assignment comma

Associativity right to left right to left

left to right

C++ also enables the programmers to overload functions. Several functions of the same name can be defined, as long as these functions have different sets of parameters (at least as far as the parameter types or the number of parameters or the order of the parameter types are concerned). This capability is called function overloading. When an overloaded function is called, the C++ compiler selects the proper function by examining the number, types and order of the arguments in the call. Function overloading is commonly used to create several functions of the same name that perform similar tasks, but on different data types. However, you cannot declare multiple functions with the same name if they only differ in their types, for example you cannot declare intf(), double f() in the same scope. Similarly, function declarations that have equivalent parameter declarations are not allowed. The following codes demonstrate the use of operator and function overloading.

//lab9a.h //header file

#ifndef PHONENUMBER_H #define PHONENUMBER_H #include<iostream> using std::ostream; using std::istream; #include<string> using std::string; class PhoneNumber { friend ostream &operator<<( ostream &, const PhoneNumber & ); friend istream &operator>>( istream &, PhoneNumber & ); private: string areaCode; // 3-digit area code string exchange; // 3-digit exchange string line; // 4-digit line }; // end class PhoneNumber #endif

// lab9a.cpp // Overloaded stream insertion and stream extraction operators // for class PhoneNumber. #include<iostream> using std::cout; using std::cin; using std::endl; #include<iomanip> using std::setw; #include"lab9a.h" // overloaded stream insertion operator; cannot be // a member function if we would like to invoke it with // cout << somePhoneNumber; ostream &operator<<( ostream &output, const PhoneNumber &number ) { output <<"("<< number.areaCode <<") " << number.exchange <<"-"<< number.line;

return output; // enables cout << a << b << c; } // end function operator<< // overloaded stream extraction operator; cannot be // a member function if we would like to invoke it with // cin >> somePhoneNumber; istream &operator>>( istream &input, PhoneNumber &number ) { input.ignore(); // skip ( input >> setw( 3 ) >> number.areaCode; // input area code input.ignore( 2 ); // skip ) and space input >> setw( 3 ) >> number.exchange; // input exchange input.ignore(); // skip dash (-) input >> setw( 4 ) >> number.line; // input line return input; // enables cin >> a >> b >> c; } // end function operator>> int main() { PhoneNumber phone; // create object phone cout <<"Enter phone number in the form (123) 456-7890:"<< endl; // cin >> phone invokes operator>> by implicitly issuing // the global function call operator>>( cin, phone ) cin >> phone; cout <<"The phone number entered was: "; // cout << phone invokes operator<< by implicitly issuing // the global function call operator<<( cout, phone ) cout << phone << endl; return 0; } // end main

The above program consists of a header file and one .cpp file. In the above example of operator overloading the stream insertion and stream extraction operators have been overloaded to perform input and output for user-defined types. The code demonstrates overloading these operators to handle data of a user-defined telephone number class called PhoneNumber. The stream extraction operator function operator>> takes istream reference input and PhoneNumber reference num as arguments and returns an istream reference. When the compiler sees the expression cin>> phone, it generates the global function call: operator>>( cin, phone );

When this call executes, reference parameter input becomes an alias for cin and reference parameter number becomes an alias for phone. The operator function reads as strings the three parts of the telephone number into the areaCode, exchange and line members of the PhoneNumber object referenced by parameter number. Similarly, the stream insertion operator function takes an ostream reference (output) and a constPhoneNumber reference (number) as arguments and returns an ostream reference. And when the compiler sees the expression cout<< phone, it generates the global function call operator<<( cout, phone ); Function operator<< displays the parts of the telephone number as strings, because they are stored as string objects. //lab9b.cpp //operator overloading on prefix and postfix increment operator. #include<iostream> using std::cout; using std::endl; class A1 { public: // member prefix ++x voidoperator++() { int x=5; cout<<"Initially x="<<x; cout<<"\tAfter using prefix increment opeartor x="<<++x<<"\n"<<endl; } }; class A2 { }; // non-member prefix ++x voidoperator++(A2&) { int x=6; cout<<"Initially x="<<x; cout<<"\tAfter using prefix increment opeartor x="<<++x<<"\n"<<endl; }

class A3 { public: // member postfix x++ voidoperator++(int) { int x=5; cout<<"Initially x="<<x; cout<<"\tAfter using postfix increment opeartor x="<<x++<<"\n"<<endl; }; }; class A4 { }; // nonmember postfix x++ voidoperator++(A4&, int) { int x=5; cout<<"Initially x="<<x; cout<<"\tAfter using postfix increment opeartor x="<<x++<<"\n"<<endl; }; int main() { A1 a1; A2 a2; A3 a3; A4 a4; // calls a1.operator++() cout<<"Function call ++a1\n"; ++a1; // explicit call, like ++a1 cout<<"Function call a1.operator++()\n"; a1.operator++(); // calls operator++(a2) cout<<"Function call ++a2\n"; ++a2; // explicit call, like ++a2 cout<<"Function call operator++(a2)\n"; operator++(a2);

// calls a3.operator++(0) // default argument of zero is supplied by compiler cout<<"Function call a3++\n"; a3++; // explicit call to member postfix a3++ cout<<"Function call a3.operator++(0)\n"; a3.operator++(0); // calls operator++(a4, 0) cout<<"Function call a4++\n"; a4++; // explicit call to non-member postfix a4++ cout<<"Function call operator++(a4,0)\n"; operator++(a4, 0); }

The above code demonstrates the overloading of prefix and postfix increment operator. The prefix increment operator ++ is overloaded with either a nonmember function operator that has one argument of class type (in this case: class type A2) or a reference to class type, or with a member function operator that has no arguments (in this case: member of class A1). Function for overloaded operator is called using both the ways in the code. Whereas, the postfix increment operator ++ can be overloaded for a class type by declaring a nonmember function operator operator++() with two arguments (in this case: class type A4), the first having class type and the second having type int. Alternatively, you can declare a member function operator operator++() with one argument having type int (in this case: class member of class A3). The compiler uses the intargument to distinguish between the prefix and postfix increment operators. For implicit calls, the default value is zero.

//lab9c.cpp //function overloading #include<iostream> usingnamespace std; void print(int i) { cout <<" Here is int "<< i << endl; }

void print(double f) { cout <<" Here is float "<< f << endl; } void print(char* c) { cout <<" Here is char* "<< c << endl; } int main() { print(10); print(10.10); print("ten"); } In the above example of function overloading the function print is overloaded to display different data types. Three functions are declared with the same name, each performing a similar operation on an int value, a double value and a string respectively. The compiler encodes each function identifier with the number and types of its parameters to enable type-safe linkage. Typesafe linkage ensures that the proper overloaded function is called and that the types of the arguments conform to the types of the parameters.

TASK(S):
1- Recode lab9b.cpp for overloading prefix and postfix decrement operator. 2- Write a code that uses function overloading such that the length of two string inputs is calculated in one function, strings are compared in another and the third function should display 1 if compared successfully and 0 if not. (HINT: first function would be having one argument, second would be having two and third function would be having one int argument).

LAB # 10 INHERITANCE

LAB OBJECTIVE
Using classes with multiple inheritances.

OVERVIEW
Inheritance is a form of software reuse in which the programmer creates a class that absorbs an existing class's data and behaviors and enhances them with new capabilities. A new class can be designated that should inherit the members of an existing class. This existing class is called the base class, and the new class is referred to as the derived class. Every derived-class object is an object of its base class, and one base class can have many derived classes. Although classes can exist independently, once they are employed in inheritance relationships, they become affiliated with other classes. A class becomes either a base class supplying members to other classes, a derived classinheriting its members from other classes, or both. A base class's private members are accessible only within the body of that base class and the friends of that base class. So we can use the access specifier protected, when dealing with inheritance. A base class's protected members can be accessed within the body of that base class, by members and friends of that base class, and by members and friends of any classes derived from that base class. Following is a code based on inheritance. //lab10.cpp //Inheritance #include<iostream> using std::cin; using std::cout; using std::endl; #include<string> using std::string; class emp //base class { public:

void get() { cout<<"Enter the employee name:"; //user input cin>>name; cout<<"Enter the designation:"; cin>>des; } protected://protected members of base class that can be accessed by the derived class string name; string des; }; class salary:public emp //derived class (inheritance) { float bs,ha,net; public: void get1() { cout<<"Enter the basic salary: "; cin>>bs; } void calculate() //claculating net salary { rate=0.05; ha=bs*rate; net=bs+ha; } void display() { cout<<"\n\nEmployee name: "<<name<<endl; cout<<"Designation: "<<des<<endl; cout<<"Basic salary: "<<bs<<endl; cout<<"Health allowance: "<<ha<<endl; cout<<"Net salary: "<<net<<endl; } private: //private member of the derived class

float rate; }; void main() { emp X; //object of base class salary Y;//object of derived class X.get(); Y.get1(); Y.calculate(); Y.display(); } The above code demonstrates a single inheritance. The class emp is the base class having a function that takes employees name and designation as input from the user. The strings storing the input are declared as protected members of the class so that the derived class can access them. The derived class is named as salary and inherits the members and data of the base class. The derived class consists of three member functions: one for taking basic salary as input, second for calculating net salary by adding health allowance to the basic salary and third function for displaying the information.

TASK(S)
1- Recode lab10.cpp to add two more derived classes based on inheritance. First class should include a function that asks for employees age and the other class should determine the gratuity for the employee based on their age. Below 50 years - no gratuity Between 50-60 years - single gratuity Above 60 years - double gratuity

LAB # 11 POLYMORPHISM

LAB OBJECTIVE
Exploring some areas of polymorphism.

OVERVIEW
Polymorphism enables us to "program in the general" rather than "program in the specific." With polymorphism, we can design and implement systems that are easily extensible new classes can be added with little or no modification to the general portions of the program, as long as the new classes are part of the inheritance hierarchy. Virtual functions and abstract classes are an important part of polymorphism and are discussed as follows. A virtual function is a function in a base class that is declared using the keyword virtual. If you specify a function in a base class as virtual and there is another definition of the function in a derived class, it signals to the compiler that you dont want static binding for this function but the selection of the function to be called at any given point in the program to be based on the kind of object for which it is called or in other words the function in the base class is over-ridden in the derived class. Choosing the appropriate function to call at execution time (rather than at compile time) is known as dynamic binding or late binding. For a function to behave as virtual, it must have the same name, parameter list, and return type in any derived class as the function has in the base class, and if the base class function is const, the derived class function must be const as well. Virtual functions can also be pure, called as pure virtual functions. A pure virtual function is specified by placing "= 0" in its declaration. The difference between a virtual function and a pure virtual function is that a virtual function has an implementation and gives the derived class the option of overriding the function; by contrast, a pure virtual function does not provide an implementation and requires the derived class to override the function. Pure virtual functions are used when it does not make sense for the base class to have an implementation of a function but the programmer wants derived classes to implement the function. Pure virtual functions usually work with abstract classes. There are some situations in which it is useful to define classes from which the programmer never intends to instantiate any objects. Such classes are called abstract classes. The purpose of an abstract class is to provide an appropriate base class from which other classes can inherit. Normally abstract classes are used as base classes in inheritance hierarchies; referred as abstract base classes. These classes cannot be used to instantiate objects and derived classes must define the "missing pieces." The derived classes used for this purpose are called concrete classes.A

class is made abstract by declaring one or more of its virtual function as pure virtual function; as pure virtual functions are not implemented in the base class. Abstract base class can be used to declare pointers and references that can refer to objects of any concrete classes derived from the abstract class. Following programs are based on virtual functions and abstract classes.

//lab11a.cpp //Virtual functions #include<iostream> using std::cout; using std::endl; class CBox // Base class { public: // Function to show the volume of an object void ShowVolume() const { cout<<Volume(); } // Function to calculate the volume of a CBox object virtualdouble Volume() const { return m_Length*m_Width*m_Height; } // Constructor CBox(double lv = 1.0, double wv = 1.0, double hv = 1.0) :m_Length(lv), m_Width(wv), m_Height(hv) {} protected: double m_Length; double m_Width; double m_Height; };

class CGlassBox: public CBox // Derived class

{ public: // Function to calculate volume of a CGlassBox // allowing 15% for packing virtualdouble Volume() const { return 0.85*m_Length*m_Width*m_Height; } // Constructor CGlassBox(double lv, double wv, double hv): CBox(lv, wv, hv){} }; int main() { CBox myBox(2.0, 3.0, 4.0); // Declaring a base box CGlassBox myGlassBox(2.0, 3.0, 4.0); // Declaring derived box cout<<"Volume of CBox: "; myBox.ShowVolume(); // Display volume of base box cout<<endl; cout<<"Volume of CGlassBox: "; myGlassBox.ShowVolume(); // Display volume of derived box cout << endl; return 0; } In this code CBox is the base class containing the virtual function Volume(). The derived class CGlassBox overrides the function definition of the virtual function for some modification. Although the keyword virtual is used in the derived class definition of the function Volume(), its not essential to do so. The first call to the function ShowVolume() with the CBox object myBox calls the CBox class version of Volume(). The second call with the CGlassBox object myGlassBox calls the version defined in the derived class. //lab11b.cpp //Abstract classes #include<iostream> usingnamespace std;

class CPolygon //Abstract base class { protected: int width, height; public: void set_values (int a, int b) { width=a; height=b; } virtualint area (void) =0; //pure virtual function void printarea (void) { cout <<this->area() << endl; } }; class CRectangle: public CPolygon { //derived class public: int area (void) { return (width * height); } }; class CTriangle: public CPolygon { //derived class public: int area (void) { return (width * height / 2); } }; int main () { CRectangle rect; //derived class objects CTriangle trgl; CPolygon * ppoly1 = &rect; //pointer to derived classes CPolygon * ppoly2 = &trgl;

ppoly1->set_values (4,5); //accessing base class members ppoly2->set_values (4,5); cout<<"Area of rectangle is: "; ppoly1->printarea(); //Area calculated according to function declaration in the class CRectangle cout<<"Area of triangle is: "; ppoly2->printarea(); //Area calculated according to function declaration in the class CTriangle return 0; } In the above code CPolygon is the base abstract class that contains the pure virtual function area(). CRectangle and CTriangle are two derived classes having different definitions for the function area() and are concrete classes. Pointers are used for derived class through which member functions are called for displaying and calculating the area. Based on the pointer declaration, functions are executed for their respective classes.

TASK(S)
1. By using virtual functions or abstract class or both, create a program that calculates the square of a number and xy (numbers x and y to be taken as input).

LAB # 12 TEMPLATES AND EXCEPTION HANDLING

LAB OBJECTIVE
Working on function and class templates and learning different techniques for exception handling.

OVERVIEW
Thislabisbasedontwodifferenttopics,templatesandexceptionhandling.Firstletsdiscusstemplates. Whenidenticaloperationsaretobeperformedondifferentdatatypes,theycanbeexpressedmore compactlyandconvenientlyusingfunctiontemplates.Forexample,wemightwriteasinglefunction templateforanarraysortfunction,andthenhavedifferentfunctioncallsforsortingintarrays,float arrays,stringarraysandsoon. Allfunctiontemplatedefinitionsbeginwithkeywordtemplatefollowedbyalistoftemplateparameters tothefunctiontemplateenclosedinanglebrackets(<and>);eachtemplateparameterthatrepresents atypemustbeprecededbyeitheroftheinterchangeablekeywordsclassortypename,asin

template<typename T > or
template<classElementType>or

template<typenameBorderType, typenameFillType>

When the function is called for a particular data type the template parameters are replaced by the data type and the arguments sent through function calling. A class template is similar to function template; we determine the class that we want to be generated by specifying our choice of type for the parameter that appears between the angled brackets in the template. Doing this generates a particular class referred to as an instance of the class template. The process of creating a class from a template is described as instantiating the template.An appropriate class definition is generated when we instantiate an object of a template class for a particular type, so any number of different classes can be generated from one class template. The other topic covered in this lab is exception handling. An exception is an indication of a problem that occurs during a program's execution. Exception handling enables programmers to create applications that can resolve (or handle) exceptions and to writefault-tolerant programs that are able to deal with problems that may arise and continue executing or terminate gracefully.

//lab12a.cpp //function templates and class templates

#include<iostream> using std::cout; using std::endl;

template<class T>//class template class mypair { T a, b; //variables a and b having type T public: mypair (T first, T second)//constructor { a=first; //setting the values b=second; }

T getmax (); };

template<typename T>//function template (we can use the word class instead of typename with T) T mypair<T>::getmax ()//function definition

{ T retval; //T type variable retval = a>b? a : b;//ternary opeartor return retval;//returning maximum value }

int main () { mypair <int> myobject (75, 100);//T replaced in the class and function with int as declared in function call cout <<"The greater number is: "<<myobject.getmax()<<endl; return 0; }

The above program compares two numbers and displays the greater one by using a class template and a function template. To indicate that we are defining a template rather than a straightforward class, we insert the keywordtemplate and the type parameter, which is T in this case, between angled brackets, just before the keyword class (keyword typename can also be used in place of class). The parameter T is the type variable that is replaced by a specific type when a class object is declared. Wherever the parameter T appears in the class definition, it is replaced by the type that isspecified in the object declaration; this creates a class definition corresponding to this type. In the code the object of the class mypair specifies the type as int and values of the two numbers are initialized using a constructor. The class contains a member function getmax() which is declared as a function template for type T. The type parameter T is again replaced by int when the function is called. The function returns the greater number of the two by using ternary operator. // lab12b.cpp //Exception handling.

#include<stdexcept>// stdexcept header file contains runtime_error using std::runtime_error; // standard C++ library class runtime_error

#include<iostream> using std::cin; using std::cout; using std::endl;

// DivideByZeroException objects should be thrown by functions // upon detecting division-by-zero exceptions class DivideByZeroException : public runtime_error { public: // constructor specifies default error message DivideByZeroException::DivideByZeroException() : runtime_error( "attempted to divide by zero" ) {} }; // end class DivideByZeroException

// perform division and throw DivideByZeroException object if // divide-by-zero exception occurs double quotient( int numerator, int denominator ) { // throw DivideByZeroException if trying to divide by zero if ( denominator == 0 ) throw DivideByZeroException(); // terminate function

// return division result returnstatic_cast<double>( numerator ) / denominator; } // end function quotient

int main() { int number1; // user-specified numerator int number2; // user-specified denominator double result; // result of division

cout <<"Enter two integers (end-of-file to end): ";

// enable user to enter two integers to divide while ( cin >> number1 >> number2 ) { // try block contains code that might throw exception // and code that should not execute if an exception occurs try { result = quotient( number1, number2 ); cout <<"The quotient is: "<< result << endl; } // end try

// exception handler handles a divide-by-zero exception

catch ( DivideByZeroException &divideByZeroException ) { cout <<"Exception occurred: " << divideByZeroException.what() << endl; } // end catch

cout <<"\nEnter two integers (end-of-file to end): "; } // end while

cout << endl; return 0; // terminate normally } // end main

The above code is an example of exception handling. The purpose of this program is to prevent a common arithmetic problem, that is, division by zero.The function quotient tests its second parameter that is denominator, to ensure that it is not zero before allowing the division to proceed. If the second parameter is zero, the function uses an exception to indicate to the caller that a problem occurred. Firstly, class DivideByZeroException is declared as a derived class of Standard Library class runtime_error (defined in header file <stdexcept>).A typical exception class that derives from the runtime_error class defines only a constructor that passes an error-message string to the baseclass runtime_error constructor. Every exception class that derives directly or indirectly from exception contains the virtual function what, which returns an exception object's error message. Try block enables exception handling. A try block consists of keyword try followed by braces ({}) that define a block of code in which exceptions might occur. The try block encloses statements that might cause exceptions and statements that should be skipped if an exception occurs. If the user inputs a 0 value as the denominator, function quotient throws an exception. As

the invocation to function quotient can throw an exception, we enclose this function invocation in a try block and output will occur only when the function returns a value. Exceptions are processed by catch handlers (also called exception handlers), which catch and handle exceptions. At least one catch handler must immediately follow each try block. Each catch handler begins with the keyword catch and specifies in parentheses an exception parameter that represents the type of exception the catch handler can process (DivideByZeroException in this case). A catch handler typically reports the error to the user, logs it to a file, terminates the program gracefully or tries an alternate strategy to accomplish the failed task when an exception occurs in the try block. In this example, the catch handler simply reports that the user attempted to divide by zero. Then the program prompts the user to enter two new integer values.

TASK(S) 1.
Create a program using function templates that takes 10 int and char values from the user and stores them in array; it should also display the values by differentiating them as odd and even.

LAB # 13 FILE PROCESSING

LAB OBJECTIVE
Working on files using console programming.

OVERVIEW
C++ views each file as a sequence of bytes. Each file ends either with an end-of-file marker or at a specific byte number recorded in a system-maintained, administrative data structure. When a file is opened, an object is created, and a stream is associated with the object. The streams associated with these objects provide communication channels between a program and a particular file or device. Files are opened by creating ifstream, ofstream or fstream objects. ifstream object is created when file is to be opened for input, ofstream is for output file and fstream object is created for file which is to be opened for both input and output. Two arguments are passed to the object's constructor the filename and the file-open mode. The file open modes are follows:

File open modes. Mode ios::app ios::ate Description Append all output to the end of the file. Open a file for output and move to the end of the file (normally used to append data to a file). Data can be written anywhere in the file. Open a file for input. Open a file for output. Discard the file's contents if they exist (this also is the default action for ios::out).

ios::in ios::out ios::trunc

ios::binary Open a file for binary (i.e., nontext) input or output.

To retrieve data sequentially from a file, programs normally start reading from the beginning of the file and read all the data consecutively until the desired data is found. It might be necessary

to process the file sequentially several times (from the beginning of the file) during the execution of a program. Both istream and ostream provide member functions for repositioning the fileposition pointer (the byte number of the next byte in the file to be read or written). These member functions are seekg ("seek get") for istream and seekp ("seek put") for ostream. The argument to seekg or seekp normally is a long integer. A second argument can be specified to indicate the seek direction. Seek directions are as follows: ios::beg (the default) ios::cur ios::end Few examples are: // position to the nth byte of fileObject (assumes ios::beg) fileObject.seekg( n ); // position n bytes forward in fileObject fileObject.seekg( n, ios::cur ); // position n bytes back from end of fileObject fileObject.seekg( n, ios::end ); // position at end of fileObject fileObject.seekg( 0, ios::end ); The same operations can be performed using ostream member function seekp. Member functions tellg and tellp are provided to return the current locations of the "get" and "put" pointers, respectively. Positions relative to the beginning of a stream Positions relative to the current position in a stream Positions relative to the end of a stream.

// lab13.cpp // writing to and reading from a sequential file #include<iostream> using std::cerr; using std::cin; using std::cout; using std::endl; using std::ios; #include<fstream>// file stream using std::fstream; // output file stream

#include<iomanip> using std::setw; using std::fixed; using std::showpoint; using std::setprecision; using std::right; using std::left; #include<cstdlib> using std::exit; // exit function prototype int main() { fstream ClientFile( "client.txt", ios::in | ios::app); // fstream constructor opens file // exit program if unable to create file if ( !ClientFile ) // overloaded ! operator { cerr <<"File could not be opened"<< endl; exit( 1 ); } // end if cout <<"Enter the account, name, and balance."<< endl <<"Enter end-of-file to end input.\n? "; int account; char name[ 30 ]; double balance; // reading account, name and balance from cin, then placing in file while ( cin >> account >> name >> balance ) { ClientFile << account <<' '<< name <<' '<< balance << endl; cout <<"? "; } // end while ClientFile.seekg( 0,ios::beg ); //repositioning file-position pointer to the beginning of the file cout << left << setw( 10 ) <<"Account"<< setw( 13 ) <<"Name"<<"Balance"<< endl << fixed << showpoint;

while ( ClientFile >> account >> name >> balance ) // displaying each record in file cout << left << setw( 10 ) << account << setw( 13 ) << name << setw( 7 ) << setprecision( 2 ) << right << balance << endl; return 0; // fstream destructor closes the file } // end main

In this program the file client.txt is opened using fstream having object ClientFile. The modes are declared for both, reading from and writing to the file as ios::in and ios::app. After creating an fstream object and attempting to open it, the program tests whether the open operation was successful. Error message is displayed in case of an unsuccessful attempt. After the file is opened successfully, the program begins processing data and prompts the user to enter either the various fields for each record or the end-of-file indicator when data entry is complete. The end-of-file key combination for Microsoft windows is <ctrl-z> (sometimes followed by pressing Enter). The data entered by the user is inserted in the file by using the stream insertion operator << and the ClientFile object. In order to check the contents of the file it is then read. Since the file is to be read from the beginning, the file-position pointer is brought to the beginning of the file by using the function seekg. File contents are then read by using the stream extraction operator >> and the ClientFile object and displayed on the screen. When the end of file has been reached the fstream destructor function closes the file and the program terminates. The programmer also can close the object explicitly, using member function close as: fileobjectname.close(). In this code it would be: ClientFile.close().

TASK(S):
1- Recode lab13.cpp to take user input which is to be inserted in the middle of the file, such that the file, if it exists, does not lose its contents when opened.

You might also like