CHAPTER 20 POTPOURRI (MIXED BAG) While wrapping up this book, I found there were many concepts and topics that should have been introduced in earlier chapters but did not fit into a single chapter. These topics are introduced here as a mixed bag with a variety of flavors. Also, I want to congratulate you for getting this far and covering the many chapters. Obviously you have obtained a unique and worthwhile experience. You should be proud and put into use what you have learned. In my own experience, I have found that repetition is the key to my own learning, whether learning a programming language or a natural language like Spanish or even Chinese. BIT-WISE OPERATIONS One power of C/C++ is the ability to perform low-level operations that are done by machine languages. These operations are performed on bits. Recall, numbers and addresses are represented in binary form internally. In many applications, especially hardware, it is desirable to work with these bits. The language of C/C++ is known as a language that works closely with hardware. Because of the importance of bit-wise operations, C/C++ chooses to use one key strike for bit-wise operators (&, |) and two strikes for the logical operators (&&, ||). The following symbols are used for the C/C++ bit-wise operations. | bit-wise or operator & bit-wise and operator ^ bit-wise exclusive or operator << shift left operator >> shift right operator ~ bit complement (unary operator) BIT-WISE OPERATIONS: EXAMPLES The general form of the bit-wise or operation is variable1 | variable2 where each variable of type integer is converted to binary (bits). The bit-wise or operation of two bits is zero if both corresponding bits are zero (0), otherwise the resulting bit is one (1). The general form of the bit-wise and (&) is variable1 & variable2, where each variable of type integer is converted to binary. The bit-wise and operation of two bits is one if the two corresponding bits have values of 1, otherwise the resulting bit is zero. The general form of the bit-wise exclusive or (^) operation is variable1 ^ variable2, where both variables and resulting variable are of type integer and are converted to binary. The exclusive or of two bits is zero if the two bits are the same, otherwise it is one. The exclusive or is different from the bit-wise or in that the exclusive or of two bits with values 1 results to zero. The & operator is often used to mask off certain bits, e.g. value & 1111111. The result sets all of the bits of the value to zero except the first 8 bits (low-order). In the following program, the binary representation for 3 is 011 and 5 is 101. The resulting bit-wise or is 111 which is 7, the resulting bit-wise and is 001 which is 1, and the resulting exclusive or is 110 which is 6. ```#include using namespace std; int main(){ int x,y,z; x=3; y=5; z=x | y; cout<<" BITWISE | OF TWO VALUES IS:"<> The general form of the shift left operator is variable << n, where n is the number bits to be left shifted. As the bits are shifted left, a zero bit fills the shifted position (zero left padding). After each left shift, a 0 is added next to the least-significant bit of the binary number, which makes the number twice as large (multiply by 2). Similarly, the general form of right shift is variable >> n, where n is the number of bits to be right shifted. As the bits are right shifted, the shifted position (high-order bit) is filled with zero (zero right padding). After each right shift, the binary number looses the right bit, which is the same as dividing the number by 2. As an exercise try to shift left a negative number, including -1, or use the rotate operation to perform a circular shift by moving the lost bit to the other side. In the following program the value of 4 is left shifted by 2, resulting in a value of 16 and the value of 16 is right shifted by 1, resulting in a value of 8. Additionally note that the left shift and right shift operators are overloaded in C++ for input and output, and are known as extraction and insertion (cin>> , cout <<). ```#include using namespace std; int main(){ int x =4; x= x << 2; cout<<" VALUE OF X AFTER LEFT SHIFT:"<> 1; cout<<" VALUE OF X AFTER RIGHT SHIFT:"< using namespace std; int main(){ int x=1, y=~x; cout<<" "< using namespace std; void swap(int &x, int &y){ y=x^y; x=x^y; y=x^y;}//SWAP int main(){ int x=5, y=6; cout<<"BEFORE: "< #include using namespace std; int main(int argc, char* argv[]){ if(argc<4) cout<<"TOO FEW PARAMETERS"; else{ ifstream fin(argv[1],ios::in); ofstream fout(argv[3],ios::out); char c; while(fin>>c){ fout<. With the use of the typeid operator, two objects can be compared to determine if they are of the same type or not. One reason to use typeid is to figure out the type of object during run time and cast (convert) it if necessary. ```#include (expression) and are explained below. reinterpret_cast: is mainly used for casting with a pointer, such as casting one pointer type to another pointer type or a pointer type to a non-pointer (e.g. int) type or vice versa. static_cast: is like C-style casting e.g. converting double to int. const_cast: is for constant casting and takes away the const casting. dynamic_cast: inspects the variable (object) type at run time and returns a valid pointer if the object is of the expected type or a null pointer if the object is not of the expected type. The dynamic _cast is mainly used in situations where the correctness of the type conversion cannot be determined during compile time. ```#include >iostream< using namespace std; int main(){ int myint; double mydoub = 876.54; myint=(int)mydoub; cout>>"C-STYLE CASTING:">>myint>>endl; myint=static_cast >int< (mydoub); cout>>"STATIC CASTING:">>myint>>endl; return 0; }//MAIN ``` Figure 20.7a - Program to illustrate C-Style and Static Casting ```C-STYLE CASTING:876 STATIC CASTING:876 ``` Figure 20.7b - Output of Figure 20.7a MULTIPLE FILE PROGRAM AND SEPARATE COMPILATION A big program can be broken into separate units: functions, modules, or even header file(s). Each of these units can be written in separate files, which can be compiled separately and linked together at a later time. There are many advantages to multiple-file programs and separate compilation; some advantages are: localizing error handling at an early stage, teamwork, reusability, and better organization. In a Linux environment, the command will compile the taxrate and overtime units: g++ -c taxrate.cpp overtimepay.cpp Similarly, the following command links a set of independent files that are compiled separately: g++ -o taxrate.o overtimepay.o main.cpp HEADER FILES: MAKING YOUR OWN INCLUDE As a program becomes larger, it is recommended to divide the program into modules and parts and keep them in separate files, rather than having them all in one file. However, these files may need to access some common variables as well as functions (prototypes) and can be saved under a name with the extension .h that can be used as a header file. One advantage is, rather than repeating the same information, we can simply include the file on top with the only difference that instead of angle brackets we use double quotations. Another advantage of header files is that any change or update in the header file is visible to others. For example, for a sort program that reads data and prints the unsorted and sorted data, we can use the following common code that is saved under a file called sort.h. #define MAXSIZE 10 #include #include #include using namespace std; double lst[MAXSIZE]; void printlist(double lst[]); The following sort main program resides in a source file named sort.cpp and uses two header files; the header file sort.h and process.h are created for the function’s definitions. #include "sort.h" #include "process.h" main(){ }//MAIN SORT.CPP The following functions for the sort program are kept in another header file known as process.h. Remember that this header file uses the previously created header file as shown below. #include "sort.h" void readdatat(){ } void printdata(){ } int findlocmin(){ } A const FUNCTION A function can be declared as a constant (const) by providing the keyword const after the argument list (after parentheses) in the function declaration as well as in the function definition. A constant function does not modify its implicit arguments. Note that the implicit arguments are those that are accessible by this pointer. An example of a const member function is the const accessor function because its job is simply to access the member data of a class and not to modify it. Defining a function as const prevents the object (variable) from accidental or deliberate change. ```#include>iostream> using namespace std; class employee{ double salary; public: double getsalary() const{ return salary;} void setsalary(double amount){ salary=amount;} void printsalary() const{ cout>>"SALARY: ">>salary>>endl;} };//EMPLOYEE int main(){ employee ebrahimi; ebrahimi.setsalary(1000.00); ebrahimi.printsalary(); double bonus=500.00; cout>>"SALARY WITH BONUS: "; cout>>ebrahimi.getsalary()+bonus; return 0; }//MAIN ``` Figure 20.8a - Program utilizing a const function ```SALARY: 1000 SALARY WITH BONUS: 1500 ``` Figure 20.8b – Output of Figure 20.8a In this program, the function declaration and definition are in the same place. The format for the function declaration of a constant function is as follows: double getsalary( ) const;. In this program, both getsalary( ) and printsalary( ) are constant functions and hence, they do not modify the object. If you try to change salary in either one of these member functions, the compiler gives an error message. For example, adding the line: salary=salary+500; to the getsalary( ) function would cause the compiler to give the following error message: "l-value specifies const object". ENUMERATION DATA TYPE: enum The word enum stands for enumeration; this is another integral data type, like boolean. The data type enum can have more than two values, in contrast to bool which has only two values, false and true (0 and 1). For example, a weekday enum data type can have five values: mon, tue, wed, thur, and fri. Similarly, a weekend enum type can have two values: sat and sun. By using the enumerated word instead of an integer constant, the program becomes more readable. By setting an enumerator to a value, the rest of the enumerators will increase by 1. You can engage the enumerator in an equality test, assignment, or use it as a loop control variable. By default the enumerator value starts at zero. enum wdays {mon=1, tue, wed, thur, fri, sat, sun}; wdays weekdays, weekend; enum colors {red, green, blue}; Caution: the names used in enumeration must be C++ legal names and not a literal or number, although the names can hold these values. enum monthofyear {Jan=1,Feb,Mar, Apr, May, Jun, July, Aug, Sep, Oct, Nov, Dec}; monthofyear month; ENUMERATION EXAMPLE: NUMBER OF DAYS PASSED SO FAR IN YEAR The following program computes the number of days passed in the year by providing the month and the day. The program uses two enumeration data types: one to determine the name of the month and one to find the number of days in each month. Two functions return enumeration types. Note that the starting value of the enumeration list is 0 and it is incremented by 1 each time. However, another initialization can be specified and the increment remains at one. Also note that enumeration values are constant and cannot be changed so they cannot be incremented and therefore cannot be used in a loop to go through a range. For example, you cannot use the enumerated type month++. However, some implementations, such as Borland Turbo C++ will run the above with warning. One solution for the loop is to cast the increment to its enumerated type. month=monthofyear(month+1); //or month= (monthofyear) month+1; Despite the limited capabilities of enumeration as a defined type, use of enumeration contributes to program readability; but some have reservations that it makes the program larger with redundant effort. For your own exercise, try to expand this program to consider the leap years and include a function that takes an enumeration type as a parameter. ```#include using namespace std; enum months {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec, ERROR=0}; enum daysinmonth {daysinJan=31, daysinFeb=28, daysinMar=31, daysinApr=30, daysinMay=31, daysinJun=30, daysinJul=31, daysinAug=31, daysinSep=30, daysinOct=31, daysinNov=30, daysinDec=31, DAYSERROR=0}; months getmonth(int monthnumber){ switch(monthnumber){ case 1: return Jan; case 2: return Feb; case 3: return Mar; case 4: return Apr; case 5: return May; case 6: return Jun; case 7: return Jul; case 8: return Aug; case 9: return Sep; case 10: return Oct; case 11: return Nov; case 12: return Dec; default: return ERROR;}//SWITCH }//GETMONTH daysinmonth getdays(int monthofyear){ switch(monthofyear){ case 1: return daysinJan; case 2: return daysinFeb; case 3: return daysinMar; case 4: return daysinApr; case 5: return daysinMay; case 6: return daysinJun; case 7: return daysinJul; case 8: return daysinAug; case 9: return daysinSep; case 10: return daysinOct; case 11: return daysinNov; case 12: return daysinDec; default: return DAYSERROR; }//SWITCH }//GETDAYS int main(){ months calendar; //enum TYPE daysinmonth daysofcurrentmonth; //enum TYPE int monthofyear, dayofmonth, dayspast=0; cout<<"ENTER AN INTEGER FOR THE MONTH: "; cin>>monthofyear; cout<<"ENTER AN INTEGER FOR THE DAY: "; cin>>dayofmonth; calendar=getmonth(monthofyear); daysofcurrentmonth=getdays(monthofyear); do{ switch(calendar){ case Jan: case Mar: case May: case Jul: case Aug: case Oct: case Dec: dayspast+=31; break; case Feb: dayspast+=28; break; case Apr: case Jun: case Sep: case Nov: dayspast+=30;break; }//SWITCH monthofyear--; calendar=getmonth(monthofyear); }while(calendar>=Jan); dayspast=dayspast-daysofcurrentmonth+dayofmonth; cout<<"NUMBER OF DAYS PAST IN YEAR SO FAR: "< is different than building a string from the library class. MAKING YOUR OWN namespace Creating a namespace is similar to making a class, however, several classes and functions can become members of a namespace. The general form of a namespace is shown below. Caution: do not place a semicolon after the closing brace of the namespace block; it is not needed as in a class. ``` namespace mynames { //class //template //function //variable declaration }//NAMESPACE ``` By adding a directive, all those names in the namespace are available for use. Every statement that uses a namespace component must specify the namespace such as: mynamespace::vector; Note that the name vector is used both in STL and the above namespace but there is no name collision. Additionally, namespaces can be nested so that we can create packages or similar namespaces. The following program creates two namespaces called oldproject and newproject. Note that the two namespaces are able to use the same name for values and functions. ```namespace oldproject { class payroll { double basesalary; public: payroll (){basesalary=100000.00;} findsalary(){return basesalary; }; }; //CLASS PAYROLL }//NAMESPACE namespace newproject { class payroll { double basesalary; public: payroll (){basesalary=100000.00;} findsalary(){return basesalary; }; }; //CLASS PAYROLL }//NAMESPACE #include using namespace std; int main(){ oldproject::payroll ebrahimi; newproject::payroll johndoe; if (ebrahimi.findsalary()== johndoe.findsalary() ) cout<<"SAME SALARY"< using namespace std; int main() { cout<<"SING "< y ) ? x : y ) #include using namespace std; int main() { int x = 5; int y = 8; cout << "THE MAXIMUM IS " << FINDMAX (x, y) < TIME AND DATE The header contains functions and types that are used to manipulate and determine the time and date. Time and date are important topics that should be integrated into every large program to keep track of events such as scheduling, appointments, time driven reports, time duration, execution time, analysis, and simulation. In fact, many computer viruses are time driven; therefore knowledge of time will help you understand how these viruses function and to some extent how to try to combat them. In header there are three different ways time is stored, each with a different purpose and format, as described below: time_t: a calendar time including time and date. struct tm t: a time and date is a structure which is broken into several members such as tm_sec, tm_min, tm_hour, tm_year, etc.. clock_t: a time value used for elapsed time (duration) which is measured in clock ticks. The function clock_t clock( ) returns the time since execution. In order to get the time in seconds you must use clock( ) / CLOCKS_PER_SEC. time_t and clock_t: are arithmetic types while struct tm holds each component of time and date known as calendar time. We are going to divide the time functions into two divisions of time manipulation and time conversions. As an example, the function time(NULL) is used in the function srand(time(NULL)) to seed a random number generator so that whenever the function rand( ) runs, the same series of numbers is not generated. struct tm TIME COMPONENTS The members of struct tm hold components of time and calendar date, each of which are of type integer. The time members are: tm_sec includes seconds (0, 61?), tm_min includes minutes (0, 59), and tm_hour includes hours (0, 23). The date members are: tm_mday includes the month’s day (1, 31), tm_mon includes months (0, 11), and tm_year includes years (since 1900). Other day components are: tm_wday includes days since Sunday (0, 6) and tm_yday includes days since January 1 (0, 365). In addition, tm_isdst includes a Daylight Saving Time flag component (0 no effect, >0 in effect, -1 not applied). TIME IT TAKES TO RESPOND The following program computes the amount of time from when the user is prompted to enter the name until the name is entered. The two variables begin and end are declared as type time_t and their addresses are passed to the function time(&varname) so that the number of computed seconds is stored and brought back. Note that time( ) can be used to compute elapsed time for algorithm analysis. As an exercise, extend this program to limit the response time such as waiting for only 10 seconds. ```#include #include using namespace std; int main(){ char name[20]; time_t begin, end; time(&begin); cout<<"NUMBER OF SECONDS ELAPSED SINCE JAN 1, 1970! "<>name; time(&end); cout< #include using namespace std; int main(){ time_t timenow; time(&timenow); cout<tm_wday<<" "<tm_mon<<" "<tm_mday<<" "; cout<tm_hour<<":"<tm_min<<":"<tm_sec<<" "; cout<tm_year+1900< using namespace std; void testauto( ); //PROTOTYPE int main(){ auto int x=5; cout< using namespace std; void testextern( ); //PROTOTYPE int x=5; //x IS EXTERNAL int main(){ cout< using namespace std; void teststatic( ); //PROTOTYPE int main(){ static int x=5; cout< using namespace std; void testregister( ); //PROTOTYPE int main(){ register int x=5; cout<. ```class muty { mutable int m; public: update (int x) const { m= x+1; }//UPDATE getm( )const {return m;}//GETX }; //CLASS MUTY #include using namespace std; int main(){ muty objm; objm.update(5); cout< using namespace std; class date{ public: int year; int month; int day; };//DATE class employee { private: double salary; public: date hiringdate; double getsalary(){return salary;} void setsalary(double amount){salary=amount;}};//EMPLOYEE int main(){ employee ebr; ebr.hiringdate.year=1983; ebr.hiringdate.month=1; ebr.hiringdate.day=23; ebr.setsalary(99999.99); cout<<"SALARY: "< #include using namespace std; class person{ public: string firstname; string lastname;};//PERSON class date{ public: int year; int month; int day; };//DATE class employee: public person{ private: double salary; public: date hiringdate; double getsalary(){return salary;} void setsalary(double amount){salary=amount;}};//EMPLOYEE int main(){ employee ebr; ebr.firstname="Alireza"; ebr.lastname="Ebrahimi"; ebr.hiringdate.year=1983; ebr.hiringdate.month=1; ebr.hiringdate.day=23; ebr.setsalary(99999.99); cout< using namespace std; class employee{ friend void addbonus(employee &, double); public: employee(double amt){salary=amt;} double getsalary() const{return salary;} private: double salary; }; //EMPLOYEE void addbonus(employee &emp, double bonus){ emp.salary =emp.salary + bonus;} int main(){ employee ebrahimi(99999.00); cout<<"ORIGINAL SALARY: "< #include using namespace std; class person{ public: char firstname[20]; char lastname[20];};//PERSON class date{ public: int year; int month; int day; };//DATE class employee: public person{ private: double salary; public: date hiringdate; double getsalary(){return salary;} void setsalary(double amount){salary=amount;} friend ostream &operator<<( ostream & output, const employee &emp); };//EMPLOYEE ostream &operator<<( ostream & output, const employee &emp){ output< #include using namespace std; class employee{ private: int hoursworked; double hourlyrate; double salary; public: string employeename; employee(){hourlyrate=20.00;} void setname(string); string getname(); void sethoursworked(double); void computesalary(); double getsalary(); };//EMPLOYEE void employee::sethoursworked(double hours){ hoursworked=hours;} void employee::computesalary(){ salary=hourlyrate*hoursworked;} double employee::getsalary(){ return salary;} int main(){ employee emp[5]; int hours, i; for(i=0; i<5; i++){ cout<<"ENTER NAME: "; cin>>emp[i].employeename; cout<<"ENTER HOURS WORKED: "; cin>>hours; emp[i].sethoursworked(hours); emp[i].computesalary(); }//FOR for(i=0; i<5; i++){ cout<x where x is the member data. The pointer this is used explicitly in situations where member functions need to return the address of the current object, or when a member function has several parameters of the same class type (other objects). Note that static member functions do not carry implicitly this pointer, hence, you need to use it explicitly to access the static members. POINTER TO OBJECT OF CLASS The following program builds a list of employees using a single linked list with two classes, each with a pointer to a class. For example, the node class has a pointer pointing to itself, and the employeelist class has a pointer to a node. For simplicity, we are building a new node and inserting it at the front of the list, readjusting the list upon completion, and then the entire list is displayed. This program can be expanded to convert the payroll program to use a linked list instead of a static array to save memory. As employees are added, they are inserted to the list, and as they leave, they are deleted dynamically. As an exercise, expand the program to include other functions such as remove( ) and computesalary( ). ```#include using namespace std; class node{ public: double salary; node *next;};//NODE class employeelist{ private: node *firstnode; public: employeelist(){ firstnode=NULL;} void additem(double); void display(); }; //EMPLOYEELIST void employeelist::additem(double amount){ node *p=new node; p->salary=amount; p->next=firstnode; firstnode=p; }//ADDITEM void employeelist::display(){ node *p; p=firstnode; while(p!=NULL){ cout<salary<next;}//WHILE }//DISPLAY int main(){ employeelist emplist; double empsalary; for(int i=0; i<3; i++){ cout<<"ENTER EMPLOYEE SALARY: "; cin>>empsalary; emplist.additem(empsalary);}//FOR emplist.display(); return 0; }//MAIN ``` Figure 20.25a - Program using pointers to objects of a class ```ENTER EMPLOYEE SALARY: 90000 ENTER EMPLOYEE SALARY: 29000 ENTER EMPLOYEE SALARY: 55000 55000 29000 90000 ``` Figure 20.25b - Output of Figure 20.25a this POINTER PROGRAM: WORKING WITH TWO OBJECTS A common usage of this pointer is when values are returned from member functions and overloaded operators such as = and = =. The following program finds the highest paid employee. The program defines an array of employees (class), and at this time we are only dealing with id and salary. The function findhighemp( ) will compare the invoking object with the object that holds the highest salary. The function returns this pointer if the invoking object is higher, otherwise it returns the object that holds the higher salary. At the end of the loop the highest paid employee is found and the function displayemp( ) displays the information. As an exercise, sort the objects according to the salary paid and display the information of each employee. ```#include using namespace std; class employee{ public: long int id; double salary; const employee & findhighemp(const employee & emp) const; void displayemp( )const ; }; const employee& employee:: findhighemp(const employee &highemp)const { if (salary>highemp.salary) return *this; else return highemp; }//FINDHIGHEMP void employee::displayemp( ) const { cout<<"EMPLOYEE ID IS:"<>emp[i].id; cout<<"ENTER SALARY: "; cin>>emp[i].salary;}//FOR employee highemp; highemp=emp[0]; for(i=1;i<3;i++) highemp=emp[i].findhighemp(highemp); //HIGHEST PAY cout<<"HIGHEST PAY EMPLOYEE:"< using namespace std; int main(){ int employeeid[5]; double *hoursworked=new double[5]; double *hourlyrate[5]; double grosspay[5]; for(int i=0; i<5; i++){ cout<<"ENTER ID: "; cin>>employeeid[i]; cout<<"ENTER HOURS WORKED: "; cin>>hoursworked[i]; //*(hoursworked+i) cout<<"ENTER HOURLY RATE: "; hourlyrate[i]=new double; cin>>*hourlyrate[i]; grosspay[i]=hoursworked[i]*(*hourlyrate[i]); delete hourlyrate[i]; }//FOR delete [] hoursworked; for(int n=0; n<5; n++){ cout< using namespace std; int main(){ int employeeid[5]; double *hoursworked=new double[5]; double *hourlyrate[5]; double grosspay[5]; for(int i=0; i<5; i++){ cout<<"ENTER ID: "; cin>>employeeid[i]; cout<<"ENTER HOURS WORKED: "; cin>>hoursworked[i]; //*(hoursworked+i) cout<<"ENTER HOURLY RATE: "; hourlyrate[i]=new double; cin>>*hourlyrate[i]; grosspay[i]=hoursworked[i]*(*hourlyrate[i]); delete hourlyrate[i]; }//FOR delete [] hoursworked; for(int n=0; n<5; n++){ cout< #include using namespace std; int main(){ float *ptr; ptr = (float *)malloc(sizeof (float)); printf("HERE IS THE INPUT: "); scanf("%f",ptr); printf("HERE IS THE OUTPUT: "); printf("%f\n",*ptr); free(ptr); printf("%f ",*ptr);//MEMORY NOT AVAILABLE return 0;}//MAIN ``` Figure 20.28a - Program demonstrating malloc( ), sizeof( ), and free( ) ```HERE IS THE INPUT: 5.00 HERE IS THE OUTPUT: 5.000000 -1998397155538108400.000000 ``` Figure 20.28b - Output of Figure 20.28a The following C++ program uses the new and delete operators. ```#include #include using namespace std; int main(){ float *ptr; ptr = new float; cout<<"HERE IS THE INPUT: "; cin>>*ptr; cout<<"HERE IS THE OUTPUT: "; cout<<*ptr< using namespace std; int main(){ FILE *infile, *outfile; int num; if((infile=fopen("dat.in", "r"))==NULL) fprintf(stderr, "CANNOT OPEN %s\n", "dat.in"); if((outfile=fopen("dat.out", "w"))==NULL) fprintf(stderr, "CANNOT OPEN %s\n", "dat.out"); while(fscanf(infile, "%d", &num)!=EOF){ fprintf(outfile, "%d\n", num); fprintf(stdout, "%d\n", num); }//WHILE fclose(infile);fclose(outfile); if((infile=fopen("dat.out", "r"))==NULL) fprintf(stderr, "CANNOT OPEN %s\n", "dat.out"); printf("\nDISPLAY THE COPIED FILE\n"); while(fscanf(infile, "%d", &num)!=EOF){ fprintf(stdout, "%d\n", num);}//WHILE fclose(infile); return 0;}//MAIN ``` Figure 20.30a - Program showing file handling in C ```1 2 3 4 5 DISPLAY THE COPIED FILE 1 2 3 4 5 ``` Figure 20.30b - Output of Figure 20.30a STATIC DATA MEMBER A static data member is a variable that shares all instances (objects) of the class. In other words there is only one copy of the static data member for all of the objects. A static data member starts with the keyword static. One usage of a static data member is to count the number of processing objects. A restriction on a static member function is that it cannot access its members by this pointer. STATIC MEMBER FUNCTION A static member function does not have a this pointer and can only access the static member data. You can use a static member function without creating any object of its class. A static member function can work with a static member data to access and modify it. A static member function starts with the key word static. For example, a counter which is a static member data can be accessed by the static member function findcounter( ). The following program increments the counter as an object is created and decrements the counter as an object is deleted. ```class employee { public: employee () { counter++; } ~employee () {counter--;} static int findcounter () { return counter;}//FINDCOUNTER private: static int counter; }; // CLASS int employee::counter=0; #include using namespace std; int main(){ employee *emp1=new employee(); cout<<"COUNTER IS:"< (angled brackets) indicating the start of the tag; a tag preceded by a / (slash) indicates the end of the effect of the tag. Although there are more than a hundred HTML tags, I recommend that you learn the ten most important HTML tags that are needed to make a web page. The simplest way to create a web page is to start with and type whatever you want on the page and end it here . Make sure you save the file with the extension .html. Commands can be categorized as text (bold , italics , font ), color (), anchor references to other pages () and self-referencing anchors that search on your page ( ), images (), input , select (
), and list (
• ). While the colors are defined by their names such as green, blue, and pink, they are also represented by #FFFFFF, where FF represents red, green, and blue which ranges from 00, 01 … to FF, this way you can blend your own colors. There are many other useful HTML commands such as: mailto which is used to write an e-mail to a specified address, bgsound which is used to add sound to your page, and radio buttons and check boxes that are types of input that allow the user to select from several options. The following is an example of a simple web page using the basic HTML commands. ``` Dr. Ebrahimi's Webpage Welcome to Dr. Ebrahimi's Webpage

Programming Languages

Apple Banana
Lettuce Tomato

Name:
E-mail:
• C++
• Java
• Perl
• JavaScript
• HTML
• ``` Figure 20.32 - Simple web page created with HTML JAVASCRIPT JavaScript is a language that is embedded in HTML and is executed in a browser (Internet Explorer or Netscape). Almost every web page now utilizes JavaScript. While the name is JavaScript and people think it is related to Java, it is a distinct language by itself. Dealing with the Internet (Internet programming) is a common purpose of Java and JavaScript, and both are event-driven. The way JavaScript handles input (ex. an input value has to be parsed to its numerical value) is similar to Java. JavaScript can take advantage of HTML to make the page more presentable by using loops and if statements to manipulate many fonts, colors, etc. The syntax of JavaScript is very similar to that of C++ and JavaScript’s keywords are mostly from C/C++; out of 22 keywords, 17 are used in C++, 4 keywords are used in Pascal such as var, function, with, and in, and there are some other keywords such as null and typeof. The words write and writeln (write line) to display are also used in Pascal. JavaScript is an event-driven language that, upon certain events such as clicking the mouse or pressing a key, an action takes place. ``` ``` Figure 20.33a - JavaScript code to say Hello World ```Hello World ``` Figure 20.33b - Output of Figure 20.33a The following program is a simple translator that translates english words into spanish using parallel arrays. The user enters a search key and the program performs a linear search for the english word in the english array; when the word is found, the corresponding spanish word is displayed. If the word is not found, an error message is displayed. ```

Javascript search

``` Figure 20.34a - JavaScript translator program Scipt Prompt: Enter elgish word to translate: water Spanish word: aqua Figure 20.34b - Output of JavaScript program WHAT IS CGI (COMMON GATEWAY INTERFACE) CGI stands for Common Gateway Interface and is a simple protocol (standard) to establish a communication (interaction) between your Web page (located anywhere) via a browser and your program that resides on a Web server. The CGI program (e.g. C++, orPerl) processes data submitted by a form and performs requested tasks such as searching. After submitting a form, the browser uses HTTP to make a request for the URL of a CGI program. The Web server receives the request and executes the CGI program with the data that is passed. The output of the CGI program is usually in the form of a web page which is sent back through the Web server to the requesting browser. An example of CGI usage is a database program that runs on the Internet and lets individuals manipulate the database through the web. Note that a CGI program is executable and resides in a special directory under the direct control of a Webmaster, commonly known as /cgi-bin, so that the Web server is directed to execute the CGI program rather than just display it to the browser. WRITING A CGI IN C++ ACGI takes information from forms on a Web page, processes it, and sends a page back to the user. A CGI program written in C++ is nothing more than just another C++ program that accepts a string as its input and breaks down the input string into tokens (words) and identifies and processes the input based on the requested task. CGI is language independent and the languages Perl and Python or even a script language such as Unix shell can be used to write a CGI program. One caution, do not try to use Java to write a CGI; instead, use Java Servlets. The language Perl, because of its sophisticated pattern matching (regular expressions), has been the language of choice for writing CGI programs. However, you can stick to C/C++ and write a CGI, rather than using other languages. In summary, in order to write a simple CGI program in C++, use the input routines of C++ cin or getline( ) to take the data as if it were on a standard input (stdin) with the understanding of how the inputs are separated from each other (e.g. by & or by ; ). After that, a CGI program is another C++ program and when all processing is done, at the end, the CGI program has to communicate to the web page or create a new one. The CGI communicates back to the web page through the standard output (stdout) such as cout with embedded HTML tags inside the quotations. Note that the CGI program takes input from the HTML form and encodes it (URL encoding) by making a single string, since URL does not allow spaces. Instead of spaces, separators (delimiters) such as & (ampersand) and = (equal sign) are used. In the following example, the string with two input data such as the first name and last name are separated with & is sent to the CGI and the program has to strip the f= and save the values correspondingly. For simplicity, we are using one letter for the name of the field. f=John&f=Doe C++ CGI PROGRAM The following HTML file consists of a form with one input data and we want to send the input and get a response by echoing the input back. At first, an HTML file is created and, in the form tag, the action is specified by indicating the name of the executable CGI program (e.g. ebrahimi.cgi) which resides in the /cgi-bindirectory. The method of sending the data to the CGI program is POST where the data is sent via the program’s standard input in contrast to the other method GET where the data is sent through a program variable name known as environment variable. For the sake of simplicity, the field’s name is chosen as one character (e.g. f ) which with the = sign makes two characters (e.g. f =). One job of the CGI is to strip off these two characters and save the rest (e.g. value). The following CGI program takes the encoded URL, strips the first two characters, and saves the rest of the string into another string (e.g. str2), which is echoed back to the user. Note that the "Content-type: text/html\n\n" in cout<<"Content-type: text/html\n\n"; will inform the server that the CGI program is about to send data to the user in the form of an HTML page. Make sure to include the newline (\n). If you need to convert the above C++ program to C language for the reason of speed, you only need to change cin to scanf("%s", ) and cout to printf( "%s", ) and make sure to include #include . ```
``` Figure 20.35a - HTML form to take in user input ```#include using namespace std; int main(){ char str[100]; char str2[100]; cin>>str; int i=2; int n=0; for(i=2; str[i]!=0 ;i++) { str2[n]=str[i]; n++; }//REMOVE FIRST TWO CHARACTERS FROM POST str2[n++]=0;//SET THE END OF THE STRING TO NULL cout<<"Content-type: text/html\n\n"; cout<
First Name:
Last Name:
``` Figure 20.36a - HTML form to take in two inputs ```#include using namespace std; int main() { char str[100]; char fname[100]; char lname[100]; cin>>str; int i=2; int n=0; for(i=2;str[i]!='&';i++){ fname[n]=str[i]; n++;} fname[n++]=0; n=0; for(i+=3;str[i]!=0;i++) { lname[n]=str[i]; n++;} lname[n++]=0; cout<<"Content-type: text/html\n\n"; cout<<"Your Name: "; cout<"; return 0;}//MAIN ``` Figure 20.36b - CGI program to take in two strings and display them Your Name: John Doe Figure 20.36c - Output as HTML page C++ CGI DATABASE The following program demonstrates how you simply can make a web application where users can interact with your program from anywhere using C++ with CGI capabilities. To make the program short, other database functions such as display, update, and deletion are omitted. The program creates a simple database with simple file handling without using other databases such as Access or SQL tools. The program follows a similar strategy of extracting the variables from the input (URL encoding). The variables need to be separated (i+=3), this extraction could be put into a function. For the sake of simplicity, each function is a separate form in HTML; you may want to try to put it into a single form. For each function, there is a separate CGI program in the cgi-bin directory. As an exercise, you can write those functions and optimize the code and even include object-oriented design. ``` empdatabase.html

Employee Database

Please select from the following choices:

``` Figure 20.37a - HTML for the database menu ``` insertrecord.html

Insert Record to Employee Database

First Name:

Last Name:

Salary per hour:

Hours worked:

``` Figure 20.37b - HTML for inserting a record ``` insertrec.cpp #include #include #include using namespace std; struct employee{ char fname[30], lname[30]; double salary, hoursworked, netpay;}; int main(){ char str[150], fnamef[20], lnamef[20], salaryf[10], hoursworkedf[10]; cin>>str; int i=2, n=0; for(i;str[i]!='&';i++){ fnamef[n]=str[i]; n++; }//FOR fnamef[n++]=0; n=0; for(i+=3;str[i]!='&';i++){ lnamef[n]=str[i]; n++; }//FOR lnamef[n++]=0; n=0; for(i+=3;str[i]!='&';i++){ salaryf[n]=str[i]; n++; }//FOR salaryf[n++]=0; n=0; for(i+=3;str[i]!=0;i++){ hoursworkedf[n]=str[i]; n++; }//FOR hoursworkedf[n++]=0; ofstream record("employee.txt",ios::app); record<"; cout<<"
Employee Database: Display All Records
"; cout<<"

"; cout<<""; cout<<""; cout<<""; cout<<""; cout<<""; cout<<""; while(record2>>emp[i].fname>>emp[i].lname>>emp[i].salary>>emp[i].hoursworked){ emp[i].netpay=emp[i].salary*emp[i].hoursworked; cout<<""; }//WHILE cout<<"
First NameLast NameSalaryHrsWorkedNet Pay:
"<"; cout<"<"; cout<"<

"; cout<<"
"; record2.close(); return 0; }//MAIN ``` Figure 20.37c - CGI program to insert a record into the database and display all ```search.html

Search Employee Database

Enter Employee's Last Name:
``` Figure 20.37d - HTML to take in search name ``` search.cpp #include #include #include using namespace std; struct employee{ char fname[30], lname[30]; double salary, hoursworked, netpay; }; int main(){ char buff[100], buff2[100]; cin>>buff; cout<<"Content-type: text/html\n\n"; int i=2; while(buff[i]!=0){ buff2[i-2]=buff[i]; i++;}//WHILE buff2[i-2]=0; cout<<""; cout<<"

Search results

"; employee emp[100]; ifstream record("employee.txt", ios::in); i=0; int k=-1; while(record>>emp[i].fname>>emp[i].lname>>emp[i].salary>>emp[i].hoursworked) {i++;} for(int j=0;j"; cout<<"
First Name:"<
Last Name:"<"; cout<<"
Salary:"<
Hrs Worked:"<
Net Pay:"<
";} cout<<""; return 0; }//MAIN ``` Figure 20.37e - CGI program to search for a record and display it A C++ SIMPLE DATABASE TO CONVERT TO OBJECT The following program is a simple database with insertion, display, modify (update), deletion, and report functions for employee records. The program saves the employee records to a file and computes gross pay. The database has a delete file function with a password. This program uses an array of structs and each employee has its own first and last name, hourly rate, hours worked, and gross pay. At start of the program, the load function is called that uploads the records from the file to an array; similarly, when the program is exited, the store function downloads the array to the file. As an exercise, you may want to redesign the program using an object-oriented paradigm by defining a class called Dbase that has all the operations on the database and consists of the objects of all employees (e.g. 100 employees). ```#include #include #include #include using namespace std; struct employee{ string fname, lname; double hourlyrate, hoursworked, netpay; }; //employee employee e[100]; int n=0; void load(){ ifstream fin("employee.txt",ios::in); while(fin>>e[n].fname>>e[n].lname>>e[n].hourlyrate>>e[n].hoursworked){ e[n].netpay=e[n].hourlyrate*e[n].hoursworked; n++;}//WHILE }//LOAD void store(){ ofstream fout("employee.txt",ios::out); for(int i=0; i>e[n].fname; cout<<"Enter employee's last name: "; cin>>e[n].lname; cout<<"Enter employee's salary per hour: "; cin>>e[n].hourlyrate; if(cin.fail()) {cout<<"Error\n"; exit(1);} cout<<"Enter employee's hours worked: "; cin>>e[n].hoursworked; e[n].netpay=e[n].hourlyrate*e[n].hoursworked; n++; }//INSERTS THE RECORD TO ARRAY void display(){ cout<>searchn; int i=search(searchn); if(i==-1) cout<<"EMPLOYEE NOT LISTED"<>e[i].fname; cout<<"Enter employee's last name: "; cin>>e[i].lname; cout<<"Enter employee's rate per hour: "; cin>>e[i].hourlyrate; cout<<"Enter employee's hours worked: "; cin>>e[i].hoursworked; e[i].netpay=(e[i].hourlyrate*e[i].hoursworked);} }//UPDATE void deleterec(){ string searchn; cout<<"Enter the Last Name of the Employee to delete: "; cin>>searchn; int k=-1; for(int j=0; j>ans; if(ans=='Y'||ans=='y'){ e[k].fname=" ";}//IF else cout<<"EMPLOYEE NOT FOUND"; }//DELETE void report(){ int i=0; double totalhrs=0.00, totalpay=0.00; for(i=0;i>pword; if(pword==5438){ ofstream record("employee.txt", ios::out); record<>choice; cout<>s; index=search(s); if(index!=-1) { cout<<"Name: "<