Blog

  • C++ Date and Time

    The C++ standard library does not provide a proper date type. C++ inherits the structs and functions for date and time manipulation from C. To access date and time related functions and structures, you would need to include <ctime> header file in your C++ program.

    There are four time-related types: clock_t, time_t, size_t, and tm. The types – clock_t, size_t and time_t are capable of representing the system time and date as some sort of integer.

    The structure type tm holds the date and time in the form of a C structure having the following elements −

    struct tm {
       int tm_sec;   // seconds of minutes from 0 to 61
       int tm_min;   // minutes of hour from 0 to 59
       int tm_hour;  // hours of day from 0 to 24
       int tm_mday;  // day of month from 1 to 31
       int tm_mon;   // month of year from 0 to 11
       int tm_year;  // year since 1900
       int tm_wday;  // days since sunday
       int tm_yday;  // days since January 1st
       int tm_isdst; // hours of daylight savings time
    }
    

    Following are the important functions, which we use while working with date and time in C or C++. All these functions are part of standard C and C++ library and you can check their detail using reference to C++ standard library given below.

    Sr.NoFunction & Purpose
    1time_t time(time_t *time);This returns the current calendar time of the system in number of seconds elapsed since January 1, 1970. If the system has no time, .1 is returned.
    2char *ctime(const time_t *time);This returns a pointer to a string of the form day month year hours:minutes:seconds year\n\0.
    3struct tm *localtime(const time_t *time);This returns a pointer to the tm structure representing local time.
    4clock_t clock(void);This returns a value that approximates the amount of time the calling program has been running. A value of .1 is returned if the time is not available.
    5char * asctime ( const struct tm * time );This returns a pointer to a string that contains the information stored in the structure pointed to by time converted into the form: day month date hours:minutes:seconds year\n\0
    6struct tm *gmtime(const time_t *time);This returns a pointer to the time in the form of a tm structure. The time is represented in Coordinated Universal Time (UTC), which is essentially Greenwich Mean Time (GMT).
    7time_t mktime(struct tm *time);This returns the calendar-time equivalent of the time found in the structure pointed to by time.
    8double difftime ( time_t time2, time_t time1 );This function calculates the difference in seconds between time1 and time2.
    9size_t strftime();This function can be used to format date and time in a specific format.

    Current Date and Time

    Suppose you want to retrieve the current system date and time, either as a local time or as a Coordinated Universal Time (UTC). Following is the example to achieve the same −

    #include <iostream>
    #include <ctime>
    
    using namespace std;
    
    int main() {
       // current date/time based on current system
       time_t now = time(0);
       
       // convert now to string form
       char* dt = ctime(&now);
    
       cout << "The local date and time is: " << dt << endl;
    
       // convert now to tm struct for UTC
       tm *gmtm = gmtime(&now);
       dt = asctime(gmtm);
       cout << "The UTC date and time is:"<< dt << endl;
    }

    When the above code is compiled and executed, it produces the following result −

    The local date and time is: Sat Jan  8 20:07:41 2011
    
    The UTC date and time is:Sun Jan  9 03:07:41 2011
    

    Format Time using struct tm

    The tm structure is very important while working with date and time in either C or C++. This structure holds the date and time in the form of a C structure as mentioned above. Most of the time related functions makes use of tm structure. Following is an example which makes use of various date and time related functions and tm structure −

    While using structure in this chapter, I’m making an assumption that you have basic understanding on C structure and how to access structure members using arrow -> operator.

    #include <iostream>
    #include <ctime>
    
    using namespace std;
    
    int main() {
       // current date/time based on current system
       time_t now = time(0);
    
       cout << "Number of sec since January 1,1970 is:: " << now << endl;
    
       tm *ltm = localtime(&now);
    
       // print various components of tm structure.
       cout << "Year:" << 1900 + ltm->tm_year<<endl;
       cout << "Month: "<< 1 + ltm->tm_mon<< endl;
       cout << "Day: "<< ltm->tm_mday << endl;
       cout << "Time: "<< 5+ltm->tm_hour << ":";
       cout << 30+ltm->tm_min << ":";
       cout << ltm->tm_sec << endl;
    }

    When the above code is compiled and executed, it produces the following result −

    Number of sec since January 1,1970 is:: 1588485717
    Year:2020
    Month: 5
    Day: 3
    Time: 11:31:57
    
  • Database Interface

    As of now, we have learnt the use of files in COBOL. Now, we will discuss how a COBOL program interacts with DB2. It involves the following terms −

    • Embedded SQL
    • DB2 Application Programming
    • Host Variables
    • SQLCA
    • SQL Queries
    • Cursors

    Embedded SQL

    Embedded SQL statements are used in COBOL programs to perform standard SQL operations. Embedded SQL statements are preprocessed by the SQL processor before the application program is compiled. COBOL is known as the Host Language. COBOL-DB2 applications are those applications that include both COBOL and DB2.

    Embedded SQL statements work like normal SQL statements with some minor changes. For example, the output of a query is directed to a predefined set of variables which are referred as Host Variables. An additional INTO clause is placed in the SELECT statement.

    DB2 Application Programming

    Following are rules to be followed while coding a COBOL-DB2 program −

    • All the SQL statements must be delimited between EXEC SQL and ENDEXEC..
    • SQL statements must be coded in Area B.
    • All the tables that are used in a program must be declared in the WorkingStorage Section. This is done by using the INCLUDE statement.
    • All SQL statements other than INCLUDE and DECLARE TABLE must appear in the Procedure Division.

    Host Variables

    Host variables are used for receiving data from a table or inserting data in a table. Host variables must be declared for all values that are to be passed between the program and the DB2. They are declared in the Working-Storage Section.

    Host variables cannot be group items, but they may be grouped together in host structure. They cannot be Renamed or Redefined. Using host variables with SQL statements, prefix them with a colon (:)..

    Syntax

    Following is the syntax to declare host variables and include tables in the Working-Storage section −

    DATA DIVISION.
       WORKING-STORAGE SECTION.
       
       EXEC SQL
       INCLUDE table-name
       END-EXEC.
    
       EXEC SQL BEGIN DECLARE SECTION
       END-EXEC.
       
       01 STUDENT-REC.
    
      05 STUDENT-ID PIC 9(4).
      05 STUDENT-NAME PIC X(25).
      05 STUDENT-ADDRESS X(50).
    EXEC SQL END DECLARE SECTION END-EXEC.

    SQLCA

    SQLCA is a SQL communication area through which DB2 passes the feedback of SQL execution to the program. It tells the program whether an execution was successful or not. There are a number of predefined variables under SQLCA like SQLCODE which contains the error code. The value ‘000’ in SQLCODE states a successful execution.

    Syntax

    Following is the syntax to declare an SQLCA in the Working-Storage section −

    DATA DIVISION.
    WORKING-STORAGE SECTION.
    	EXEC SQL
    	INCLUDE SQLCA
    	END-EXEC.
    

    SQL Queries

    Let’s assume we have one table named as ‘Student’ that contains Student-Id, Student-Name, and Student-Address.

    The STUDENT table contains the following data −

    Student Id		Student Name		Student Address
    1001 			   Mohtashim M.		Hyderabad
    1002			   Nishant Malik		Delhi
    1003 			   Amitabh Bachan		Mumbai
    1004			   Chulbul Pandey		Lucknow
    

    The following example shows the usage of SELECT query in a COBOL program −

    IDENTIFICATION DIVISION.
    PROGRAM-ID. HELLO.
    
    DATA DIVISION.
       WORKING-STORAGE SECTION.
       EXEC SQL
    
      INCLUDE SQLCA
    END-EXEC. EXEC SQL
      INCLUDE STUDENT
    END-EXEC. EXEC SQL BEGIN DECLARE SECTION END-EXEC.
      01 WS-STUDENT-REC.
         05 WS-STUDENT-ID PIC 9(4).
         05 WS-STUDENT-NAME PIC X(25).
         05 WS-STUDENT-ADDRESS X(50).
    EXEC SQL END DECLARE SECTION END-EXEC. PROCEDURE DIVISION. EXEC SQL
      SELECT STUDENT-ID, STUDENT-NAME, STUDENT-ADDRESS
      INTO :WS-STUDENT-ID, :WS-STUDENT-NAME, WS-STUDENT-ADDRESS FROM STUDENT
      WHERE STUDENT-ID=1004
    END-EXEC. IF SQLCODE = 0
      DISPLAY WS-STUDENT-RECORD
    ELSE DISPLAY 'Error' END-IF. STOP RUN.

    JCL to execute the above COBOL program −

    //SAMPLE JOB(TESTJCL,XXXXXX),CLASS = A,MSGCLASS = C
    //STEP001  EXEC PGM = IKJEFT01
    //STEPLIB  DD DSN = MYDATA.URMI.DBRMLIB,DISP = SHR
    //SYSPRINT DD SYSOUT=*
    //SYSUDUMP DD SYSOUT=*
    //SYSOUT   DD SYSOUT=*
    //SYSTSIN  DD *
       DSN SYSTEM(SSID)
       RUN PROGRAM(HELLO) PLAN(PLANNAME) -
       END
    /*

    When you compile and execute the above program, it produces the following result −

    1004 Chulbul Pandey		Lucknow
    

    The following example shows the usage of INSERT query in a COBOL program −

    IDENTIFICATION DIVISION.
    PROGRAM-ID. HELLO.
    
    DATA DIVISION.
       WORKING-STORAGE SECTION.
       EXEC SQL
       INCLUDE SQLCA
       END-EXEC.
       
       EXEC SQL
       INCLUDE STUDENT
       END-EXEC.
       
       EXEC SQL BEGIN DECLARE SECTION
       END-EXEC.
    
      01 WS-STUDENT-REC.
         05 WS-STUDENT-ID PIC 9(4).
         05 WS-STUDENT-NAME PIC X(25).
         05 WS-STUDENT-ADDRESS X(50).
    EXEC SQL END DECLARE SECTION END-EXEC. PROCEDURE DIVISION. MOVE 1005 TO WS-STUDENT-ID. MOVE 'TutorialsPoint' TO WS-STUDENT-NAME. MOVE 'Hyderabad' TO WS-STUDENT-ADDRESS. EXEC SQL
      INSERT INTO STUDENT(STUDENT-ID, STUDENT-NAME, STUDENT-ADDRESS)
      VALUES (:WS-STUDENT-ID, :WS-STUDENT-NAME, WS-STUDENT-ADDRESS)
    END-EXEC. IF SQLCODE = 0
      DISPLAY 'Record Inserted Successfully'
      DISPLAY WS-STUDENT-REC
    ELSE DISPLAY 'Error' END-IF. STOP RUN.

    JCL to execute the above COBOL program −

    //SAMPLE JOB(TESTJCL,XXXXXX),CLASS = A,MSGCLASS = C
    //STEP001  EXEC PGM = IKJEFT01
    //STEPLIB  DD DSN = MYDATA.URMI.DBRMLIB,DISP=SHR
    //SYSPRINT DD SYSOUT = *
    //SYSUDUMP DD SYSOUT = *
    //SYSOUT   DD SYSOUT = *
    //SYSTSIN  DD *
       DSN SYSTEM(SSID)
       RUN PROGRAM(HELLO) PLAN(PLANNAME) -
       END
    /*

    When you compile and execute the above program, it produces the following result −

    Record Inserted Successfully
    1005 TutorialsPoint		Hyderabad
    

    The following example shows the usage of UPDATE query in a COBOL program −

    IDENTIFICATION DIVISION.
    PROGRAM-ID. HELLO.
    
    DATA DIVISION.
       WORKING-STORAGE SECTION.
       
       EXEC SQL
       INCLUDE SQLCA
       END-EXEC.
       
       EXEC SQL
       INCLUDE STUDENT
       END-EXEC.
       
       EXEC SQL BEGIN DECLARE SECTION
       END-EXEC.
    
      01 WS-STUDENT-REC.
         05 WS-STUDENT-ID PIC 9(4).
         05 WS-STUDENT-NAME PIC X(25).
         05 WS-STUDENT-ADDRESS X(50).
    EXEC SQL END DECLARE SECTION END-EXEC. PROCEDURE DIVISION. MOVE 'Bangalore' TO WS-STUDENT-ADDRESS. EXEC SQL
      UPDATE STUDENT SET STUDENT-ADDRESS=:WS-STUDENT-ADDRESS
      WHERE STUDENT-ID = 1003
    END-EXEC. IF SQLCODE = 0
      DISPLAY 'Record Updated Successfully'
    ELSE DISPLAY 'Error' END-IF. STOP RUN.

    JCL to execute the above COBOL program −

    //SAMPLE JOB(TESTJCL,XXXXXX),CLASS = A,MSGCLASS = C
    //STEP001  EXEC PGM = IKJEFT01
    //STEPLIB  DD DSN = MYDATA.URMI.DBRMLIB,DISP = SHR
    //SYSPRINT DD SYSOUT = *
    //SYSUDUMP DD SYSOUT = *
    //SYSOUT   DD SYSOUT = *
    //SYSTSIN  DD *
       DSN SYSTEM(SSID)
       RUN PROGRAM(HELLO) PLAN(PLANNAME) -
       END
    /*

    When you compile and execute the above program, it produces the following result −

    Record Updated Successfully
    

    The following example shows the usage of DELETE query in a COBOL program −

    IDENTIFICATION DIVISION.
    PROGRAM-ID. HELLO.
    
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    
       EXEC SQL
       INCLUDE SQLCA
       END-EXEC.
       
       EXEC SQL
       INCLUDE STUDENT
       END-EXEC.
       
       EXEC SQL BEGIN DECLARE SECTION
       END-EXEC.
    
      01 WS-STUDENT-REC.
         05 WS-STUDENT-ID PIC 9(4).
         05 WS-STUDENT-NAME PIC X(25).
         05 WS-STUDENT-ADDRESS X(50).
    EXEC SQL END DECLARE SECTION END-EXEC. PROCEDURE DIVISION. MOVE 1005 TO WS-STUDENT-ID. EXEC SQL
      DELETE FROM STUDENT
      WHERE STUDENT-ID=:WS-STUDENT-ID
    END-EXEC. IF SQLCODE = 0
      DISPLAY 'Record Deleted Successfully'
    ELSE DISPLAY 'Error' END-IF. STOP RUN.

    JCL to execute the above COBOL program −

    //SAMPLE JOB(TESTJCL,XXXXXX),CLASS = A,MSGCLASS = C
    //STEP001  EXEC PGM = IKJEFT01
    //STEPLIB  DD DSN = MYDATA.URMI.DBRMLIB,DISP=SHR
    //SYSPRINT DD SYSOUT = *
    //SYSUDUMP DD SYSOUT = *
    //SYSOUT   DD SYSOUT = *
    //SYSTSIN  DD *
       DSN SYSTEM(SSID)
       RUN PROGRAM(HELLO) PLAN(PLANNAME) -
       END
    /*

    When you compile and execute the above program, it produces the following result −

    Record Deleted Successfully
    

    Cursors

    Cursors are used to handle multiple row selections at a time. They are data structures that hold all the results of a query. They can be defined in the Working-Storage Section or the Procedure Division. Following are the operations associated with Cursor −

    • Declare
    • Open
    • Close
    • Fetch

    Declare Cursor

    Cursor declaration can be done in the Working-Storage Section or the Procedure Division. The first statement is the DECLARE statement which is a nonexecutable statement.

    EXEC SQL
       DECLARE STUDCUR CURSOR FOR
       SELECT STUDENT-ID, STUDENT-NAME, STUDENT-ADDRESS FROM STUDENT
       WHERE STUDENT-ID >:WS-STUDENT-ID
    END-EXEC.

    Open

    Before using a cursor, Open statement must be performed. The Open statement prepares the SELECT for execution.

    EXEC SQL
       OPEN STUDCUR
    END-EXEC.

    Close

    Close statement releases all the memory occupied by the cursor. It is mandatory to close a cursor before ending a program.

    EXEC SQL
       CLOSE STUDCUR
    END-EXEC.

    Fetch

    Fetch statement identifies the cursor and puts the value in the INTO clause. A Fetch statement is coded in loop as we get one row at a time.

    EXEC SQL
       FETCH STUDCUR
       INTO :WS-STUDENT-ID, :WS-STUDENT-NAME, WS-STUDENT-ADDRESS
    END-EXEC.

    The following example shows the usage of cursor to fetch all the records from the STUDENT table −

    IDENTIFICATION DIVISION.
    PROGRAM-ID. HELLO.
    
    DATA DIVISION.
       WORKING-STORAGE SECTION.
       
       EXEC SQL
       INCLUDE SQLCA
       END-EXEC.
       
       EXEC SQL
       INCLUDE STUDENT
       END-EXEC.
       
       EXEC SQL BEGIN DECLARE SECTION
       END-EXEC.
    
      01 WS-STUDENT-REC.
         05 WS-STUDENT-ID PIC 9(4).
         05 WS-STUDENT-NAME PIC X(25).
         05 WS-STUDENT-ADDRESS X(50).
    EXEC SQL END DECLARE SECTION END-EXEC. EXEC SQL
      DECLARE STUDCUR CURSOR FOR
      SELECT STUDENT-ID, STUDENT-NAME, STUDENT-ADDRESS FROM STUDENT
      WHERE STUDENT-ID &gt;:WS-STUDENT-ID
    END-EXEC. PROCEDURE DIVISION. MOVE 1001 TO WS-STUDENT-ID. PERFORM UNTIL SQLCODE = 100 EXEC SQL
      FETCH STUDCUR
      INTO :WS-STUDENT-ID, :WS-STUDENT-NAME, WS-STUDENT-ADDRESS
    END-EXEC DISPLAY WS-STUDENT-REC END-PERFORM STOP RUN.

    JCL to execute the above COBOL program −

    //SAMPLE JOB(TESTJCL,XXXXXX),CLASS = A,MSGCLASS = C
    //STEP001  EXEC PGM=IKJEFT01
    //STEPLIB  DD DSN=MYDATA.URMI.DBRMLIB,DISP=SHR
    //SYSPRINT DD SYSOUT=*
    //SYSUDUMP DD SYSOUT=*
    //SYSOUT   DD SYSOUT=*
    //SYSTSIN  DD *
       DSN SYSTEM(SSID)
       RUN PROGRAM(HELLO) PLAN(PLANNAME) -
       END
    /*

    When you compile and execute the above program, it produces the following result −

    1001 Mohtashim M.		Hyderabad
    1002 Nishant Malik		Delhi
    1003 Amitabh Bachan		Mumbai
    1004 Chulbul Pandey		Lucknow
    
  • C++ References

    A reference variable is an alias, that is, another name for an already existing variable. Once a reference is initialized with a variable, either the variable name or the reference name may be used to refer to the variable.

    References vs Pointers

    References are often confused with pointers but three major differences between references and pointers are −

    • You cannot have NULL references. You must always be able to assume that a reference is connected to a legitimate piece of storage.
    • Once a reference is initialized to an object, it cannot be changed to refer to another object. Pointers can be pointed to another object at any time.
    • A reference must be initialized when it is created. Pointers can be initialized at any time.

    Creating References in C++

    Think of a variable name as a label attached to the variable’s location in memory. You can then think of a reference as a second label attached to that memory location. Therefore, you can access the contents of the variable through either the original variable name or the reference. For example, suppose we have the following example −

    int i = 17;
    

    We can declare reference variables for i as follows.

    int& r = i;
    

    Read the & in these declarations as reference. Thus, read the first declaration as “r is an integer reference initialized to i” and read the second declaration as “s is a double reference initialized to d.”. Following example makes use of references on int and double −

    #include <iostream>
     
    using namespace std;
     
    int main () {
       // declare simple variables
       int    i;
       double d;
     
       // declare reference variables
       int&    r = i;
       double& s = d;
       
       i = 5;
       cout << "Value of i : " << i << endl;
       cout << "Value of i reference : " << r  << endl;
     
       d = 11.7;
       cout << "Value of d : " << d << endl;
       cout << "Value of d reference : " << s  << endl;
       
       return 0;
    }

    When the above code is compiled together and executed, it produces the following result −

    Value of i : 5
    Value of i reference : 5
    Value of d : 11.7
    Value of d reference : 11.7
    

    References are usually used for function argument lists and function return values. So following are two important subjects related to C++ references which should be clear to a C++ programmer −

    Sr.NoConcept & Description
    1References as ParametersC++ supports passing references as function parameter more safely than parameters.
    2Reference as Return ValueYou can return reference from a C++ function like any other data type.
  • C++ Pointers

    C++ pointers are easy and fun to learn. Some C++ tasks are performed more easily with pointers, and other C++ tasks, such as dynamic memory allocation, cannot be performed without them.

    As you know every variable is a memory location and every memory location has its address defined which can be accessed using ampersand (&) operator which denotes an address in memory. Consider the following which will print the address of the variables defined −

    #include <iostream>
    
    using namespace std;
    int main () {
       int  var1;
       char var2[10];
    
       cout << "Address of var1 variable: ";
       cout << &var1 << endl;
    
       cout << "Address of var2 variable: ";
       cout << &var2 << endl;
    
       return 0;
    }

    When the above code is compiled and executed, it produces the following result −

    Address of var1 variable: 0xbfebd5c0
    Address of var2 variable: 0xbfebd5b6
    

    What are Pointers?

    pointer is a variable whose value is the address of another variable. Like any variable or constant, you must declare a pointer before you can work with it. The general form of a pointer variable declaration is −

    type *var-name;
    

    Here, type is the pointer’s base type; it must be a valid C++ type and var-name is the name of the pointer variable. The asterisk you used to declare a pointer is the same asterisk that you use for multiplication. However, in this statement the asterisk is being used to designate a variable as a pointer. Following are the valid pointer declaration −

    int    *ip;    // pointer to an integer
    double *dp;    // pointer to a double
    float  *fp;    // pointer to a float
    char   *ch     // pointer to character
    

    The actual data type of the value of all pointers, whether integer, float, character, or otherwise, is the same, a long hexadecimal number that represents a memory address. The only difference between pointers of different data types is the data type of the variable or constant that the pointer points to.

    Using Pointers in C++

    There are few important operations, which we will do with the pointers very frequently. (a) We define a pointer variable. (b) Assign the address of a variable to a pointer. (c) Finally access the value at the address available in the pointer variable. This is done by using unary operator * that returns the value of the variable located at the address specified by its operand. Following example makes use of these operations −

    #include <iostream>
    
    using namespace std;
    
    int main () {
       int  var = 20;   // actual variable declaration.
       int  *ip;        // pointer variable 
    
       ip = &var;       // store address of var in pointer variable
    
       cout << "Value of var variable: ";
       cout << var << endl;
    
       // print the address stored in ip pointer variable
       cout << "Address stored in ip variable: ";
       cout << ip << endl;
    
       // access the value at the address available in pointer
       cout << "Value of *ip variable: ";
       cout << *ip << endl;
    
       return 0;
    }

    When the above code is compiled and executed, it produces result something as follows −

    Value of var variable: 20
    Address stored in ip variable: 0xbfc601ac
    Value of *ip variable: 20
    

    Pointers in C++

    Pointers have many but easy concepts and they are very important to C++ programming. There are following few important pointer concepts which should be clear to a C++ programmer −

    Sr.NoConcept & Description
    1Null PointersC++ supports null pointer, which is a constant with a value of zero defined in several standard libraries.
    2Pointer ArithmeticThere are four arithmetic operators that can be used on pointers: ++, –, +, –
    3Pointers vs ArraysThere is a close relationship between pointers and arrays.
    4Array of PointersYou can define arrays to hold a number of pointers.
    5Pointer to PointerC++ allows you to have pointer on a pointer and so on.
    6Passing Pointers to FunctionsPassing an argument by reference or by address both enable the passed argument to be changed in the calling function by the called function.
    7Return Pointer from FunctionsC++ allows a function to return a pointer to local variable, static variable and dynamically allocated memory as well.
  • C++ Strings

    C++ provides following two types of string representations −

    • The C-style character string.
    • The string class type introduced with Standard C++.

    The C-Style Character String

    The C-style character string originated within the C language and continues to be supported within C++. This string is actually a one-dimensional array of characters which is terminated by a null character ‘\0’. Thus a null-terminated string contains the characters that comprise the string followed by a null.

    The following declaration and initialization create a string consisting of the word “Hello”. To hold the null character at the end of the array, the size of the character array containing the string is one more than the number of characters in the word “Hello.”

    char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
    

    If you follow the rule of array initialization, then you can write the above statement as follows −

    char greeting[] = "Hello";
    

    Following is the memory presentation of above defined string in C/C++ −

    String Presentation in C/C++

    Actually, you do not place the null character at the end of a string constant. The C++ compiler automatically places the ‘\0’ at the end of the string when it initializes the array. Let us try to print above-mentioned string −

    #include <iostream>
    
    using namespace std;
    
    int main () {
    
       char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
    
       cout << "Greeting message: ";
       cout << greeting << endl;
    
       return 0;
    }

    When the above code is compiled and executed, it produces the following result −

    Greeting message: Hello
    

    C++ supports a wide range of functions that manipulate null-terminated strings −

    Sr.NoFunction & Purpose
    1strcpy(s1, s2);Copies string s2 into string s1.
    2strcat(s1, s2);Concatenates string s2 onto the end of string s1.
    3strlen(s1);Returns the length of string s1.
    4strcmp(s1, s2);Returns 0 if s1 and s2 are the same; less than 0 if s1<s2; greater than 0 if s1>s2.
    5strchr(s1, ch);Returns a pointer to the first occurrence of character ch in string s1.
    6strstr(s1, s2);Returns a pointer to the first occurrence of string s2 in string s1.

    Following example makes use of few of the above-mentioned functions −

    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    int main () {
    
       char str1[10] = "Hello";
       char str2[10] = "World";
       char str3[10];
       int  len ;
    
       // copy str1 into str3
       strcpy( str3, str1);
       cout << "strcpy( str3, str1) : " << str3 << endl;
    
       // concatenates str1 and str2
       strcat( str1, str2);
       cout << "strcat( str1, str2): " << str1 << endl;
    
       // total lenghth of str1 after concatenation
       len = strlen(str1);
       cout << "strlen(str1) : " << len << endl;
    
       return 0;
    }

    When the above code is compiled and executed, it produces result something as follows −

    strcpy( str3, str1) : Hello
    strcat( str1, str2): HelloWorld
    strlen(str1) : 10
    

    The String Class in C++

    The standard C++ library provides a string class type that supports all the operations mentioned above, additionally much more functionality. Let us check the following example −

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main () {
    
       string str1 = "Hello";
       string str2 = "World";
       string str3;
       int  len ;
    
       // copy str1 into str3
       str3 = str1;
       cout << "str3 : " << str3 << endl;
    
       // concatenates str1 and str2
       str3 = str1 + str2;
       cout << "str1 + str2 : " << str3 << endl;
    
       // total length of str3 after concatenation
       len = str3.size();
       cout << "str3.size() :  " << len << endl;
    
       return 0;
    }

    When the above code is compiled and executed, it produces result something as follows −

    str3 : Hello
    str1 + str2 : HelloWorld
    str3.size() :  10
    
  • Internal Sort

    Sorting of data in a file or merging of two or more files is a common necessity in almost all business-oriented applications. Sorting is used for arranging records either in ascending or descending order, so that sequential processing can be performed. There are two techniques which are used for sorting files in COBOL −

    • External sort is used to sort files by using the SORT utility in JCL. We have discussed this in the JCL chapter. As of now, we will focus on internal sort.
    • Internal sort is used to sort files within a COBOL program. SORT verb is used to sort a file.

    Sort Verb

    Three files are used in the sort process in COBOL −

    • Input file is the file which we have to sort either in ascending or descending order.
    • Work file is used to hold records while the sort process is in progress. Input file records are transferred to the work file for the sorting process. This file should be defined in the File-Section under SD entry.
    • Output file is the file which we get after the sorting process. It is the final output of the Sort verb.

    Syntax

    Following is the syntax to sort a file −

    SORT work-file ON ASCENDING KEY rec-key1
       [ON DESCENDING KEY rec-key2]
    USING input-file GIVING output-file.
    

    SORT performs the following operations −

    • Opens work-file in I-O mode, input-file in the INPUT mode and output-file in the OUTPUT mode.
    • Transfers the records present in the input-file to the work-file.
    • Sorts the SORT-FILE in ascending/descending sequence by rec-key.
    • Transfers the sorted records from the work-file to the output-file.
    • Closes the input-file and the output-file and deletes the work-file.

    Example

    In the following example, INPUT is the input file which needs to be sorted in ascending order −

    IDENTIFICATION DIVISION.
    PROGRAM-ID. HELLO.
    
    ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
    
      SELECT INPUT ASSIGN TO IN.
      SELECT OUTPUT ASSIGN TO OUT.
      SELECT WORK ASSIGN TO WRK.
    DATA DIVISION. FILE SECTION. FD INPUT.
      01 INPUT-STUDENT.
         05 STUDENT-ID-I PIC 9(5).
         05 STUDENT-NAME-I PIC A(25).
    FD OUTPUT.
      01 OUTPUT-STUDENT.
         05 STUDENT-ID-O PIC 9(5).
         05 STUDENT-NAME-O PIC A(25).
    SD WORK.
      01 WORK-STUDENT.
         05 STUDENT-ID-W PIC 9(5).
         05 STUDENT-NAME-W PIC A(25).
    PROCEDURE DIVISION. SORT WORK ON ASCENDING KEY STUDENT-ID-O USING INPUT GIVING OUTPUT. DISPLAY 'Sort Successful'. STOP RUN.

    JCL to execute the above COBOL program −

    //SAMPLE JOB(TESTJCL,XXXXXX),CLASS = A,MSGCLASS = C
    //STEP1 EXEC PGM = HELLO
    //IN DD DSN = INPUT-FILE-NAME,DISP = SHR
    //OUT DD DSN = OUTPUT-FILE-NAME,DISP = SHR
    //WRK DD DSN = &&TEMP

    When you compile and execute the above program, it produces the following result −

    Sort Successful
    

    Merge Verb

    Two or more identically sequenced files are combined using Merge statement. Files used in the merge process −

    • Input Files − Input-1, Input-2
    • Work File
    • Output File

    Syntax

    Following is the syntax to merge two or more files −

    MERGE work-file ON ASCENDING KEY rec-key1
       [ON DESCENDING KEY rec-key2]
    
    USING input-1, input-2 GIVING output-file.

    Merge performs the following operations −

    • Opens the work-file in I-O mode, input-files in the INPUT mode and output-file in the OUTPUT mode.
    • Transfers the records present in the input-files to the work-file.
    • Sorts the SORT-FILE in ascending/descending sequence by rec-key.
    • Transfers the sorted records from the work-file to the output-file.
    • Closes the input-file and the output-file and deletes the work-file.

    Example

    In the following example, INPUT1 and INPUT2 are the input files which are to be merged in ascending order −

    IDENTIFICATION DIVISION.
    PROGRAM-ID. HELLO.
    
    ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
    
      SELECT INPUT1 ASSIGN TO IN1.
      SELECT INPUT2 ASSIGN TO IN2.
      SELECT OUTPUT ASSIGN TO OUT.
      SELECT WORK ASSIGN TO WRK.
    DATA DIVISION. FILE SECTION. FD INPUT1.
      01 INPUT1-STUDENT.
         05 STUDENT-ID-I1 PIC 9(5).
         05 STUDENT-NAME-I1 PIC A(25).
    FD INPUT2.
      01 INPUT2-STUDENT.
         05 STUDENT-ID-I2 PIC 9(5).
         05 STUDENT-NAME-I2 PIC A(25).
    FD OUTPUT.
      01 OUTPUT-STUDENT.
         05 STUDENT-ID-O PIC 9(5).
         05 STUDENT-NAME-O PIC A(25).
    SD WORK.
      01 WORK-STUDENT.
         05 STUDENT-ID-W PIC 9(5).
         05 STUDENT-NAME-W PIC A(25).
    PROCEDURE DIVISION. MERGE WORK ON ASCENDING KEY STUDENT-ID-O USING INPUT1, INPUT2 GIVING OUTPUT. DISPLAY 'Merge Successful'. STOP RUN.

    JCL to execute the above COBOL program −

    //SAMPLE JOB(TESTJCL,XXXXXX),CLASS = A,MSGCLASS = C
    //STEP1 EXEC PGM = HELLO
    //IN1 DD DSN=INPUT1-FILE-NAME,DISP=SHR
    //IN2 DD DSN=INPUT2-FILE-NAME,DISP=SHR
    //OUT DD DSN = OUTPUT-FILE-NAME,DISP=SHR
    //WRK DD DSN = &&TEMP

    When you compile and execute the above program, it produces the following result −

    Merge Successful
    
  • C++ Arrays

    C++ provides a data structure, the array, which stores a fixed-size sequential collection of elements of the same type. An array is used to store a collection of data, but it is often more useful to think of an array as a collection of variables of the same type.

    Instead of declaring individual variables, such as number0, number1, …, and number99, you declare one array variable such as numbers and use numbers[0], numbers[1], and …, numbers[99] to represent individual variables. A specific element in an array is accessed by an index.

    All arrays consist of contiguous memory locations. The lowest address corresponds to the first element and the highest address to the last element.

    Declaring Arrays

    To declare an array in C++, the programmer specifies the type of the elements and the number of elements required by an array as follows −

    type arrayName [ arraySize ];
    

    This is called a single-dimension array. The arraySize must be an integer constant greater than zero and type can be any valid C++ data type. For example, to declare a 10-element array called balance of type double, use this statement −

    double balance[10];
    

    Initializing Arrays

    You can initialize C++ array elements either one by one or using a single statement as follows −

    double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
    

    The number of values between braces { } can not be larger than the number of elements that we declare for the array between square brackets [ ]. Following is an example to assign a single element of the array −

    If you omit the size of the array, an array just big enough to hold the initialization is created. Therefore, if you write −

    double balance[] = {1000.0, 2.0, 3.4, 17.0, 50.0};
    

    You will create exactly the same array as you did in the previous example.

    balance[4] = 50.0;
    

    The above statement assigns element number 5th in the array a value of 50.0. Array with 4th index will be 5th, i.e., last element because all arrays have 0 as the index of their first element which is also called base index. Following is the pictorial representaion of the same array we discussed above −

    Array Presentation

    Accessing Array Elements

    An element is accessed by indexing the array name. This is done by placing the index of the element within square brackets after the name of the array. For example −

    double salary = balance[9];
    

    The above statement will take 10th element from the array and assign the value to salary variable. Following is an example, which will use all the above-mentioned three concepts viz. declaration, assignment and accessing arrays −

    #include <iostream>
    using namespace std;
     
    #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++ ) {
    
      n&#91; i ] = i + 100; // set element at location i to i + 100
    } cout << "Element" << setw( 13 ) << "Value" << endl; // output each array element's value for ( int j = 0; j < 10; j++ ) {
      cout &lt;&lt; setw( 7 )&lt;&lt; j &lt;&lt; setw( 13 ) &lt;&lt; n&#91; j ] &lt;&lt; endl;
    } return 0; }

    This program makes use of setw() function to format the output. When the above code is compiled and executed, it produces the following result −

    Element        Value
    
      0          100
      1          101
      2          102
      3          103
      4          104
      5          105
      6          106
      7          107
      8          108
      9          109

    Arrays in C++

    Arrays are important to C++ and should need lots of more detail. There are following few important concepts, which should be clear to a C++ programmer −

    Sr.NoConcept & Description
    1Multi-dimensional arraysC++ supports multidimensional arrays. The simplest form of the multidimensional array is the two-dimensional array.
    2Pointer to an arrayYou can generate a pointer to the first element of an array by simply specifying the array name, without any index.
    3Passing arrays to functionsYou can pass to the function a pointer to an array by specifying the array’s name without an index.
    4Return array from functionsC++ allows a function to return an array.
  • Subroutines

    Cobol subroutine is a program that can be compiled independently but cannot be executed independently. There are two types of subroutines: internal subroutines like Perform statements and external subroutines like CALL verb.

    Call Verb

    Call verb is used to transfer the control from one program to another program. The program that contains the CALL verb is the Calling Program and the program being called is known as the Called Program. Calling program execution will halt until the called program finishes the execution. Exit Program statement is used in the Called program to transfer the control back.

    Called Program Constraints

    Following are the called program requirements −

    • Linkage section must be defined in the called program. It consists of data elements passed in the program. The data items should not have Value clause. PIC clause must be compatible with the variables passed through the calling program.
    • Procedure division using has a list of variables passed from the calling program and the order must be same as mentioned in the Call verb.
    • Exit program statement is used in the called program to transfer the control back. It must be the last statement in the called program.

    The parameters can be passed between programs in two ways −

    • By Reference
    • By Content

    Call By Reference

    If the values of variables in the called program are modified, then their new values will reflect in the calling program. If BY clause is not specified, then variables are always passed by reference.

    Syntax

    Following is the syntax of calling subroutine by reference −

    CALL sub-prog-name USING variable-1, variable-2.
    

    Example

    Following example is the MAIN calling program and UTIL is the called program −

    IDENTIFICATION DIVISION.
    PROGRAM-ID. MAIN.
    
    DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-STUDENT-ID PIC 9(4) VALUE 1000.
       01 WS-STUDENT-NAME PIC A(15) VALUE 'Tim'.
    
    PROCEDURE DIVISION.
       CALL 'UTIL' USING WS-STUDENT-ID, WS-STUDENT-NAME.
       DISPLAY 'Student Id : ' WS-STUDENT-ID
       DISPLAY 'Student Name : ' WS-STUDENT-NAME
    STOP RUN.

    Called Program

    IDENTIFICATION DIVISION.
    PROGRAM-ID. UTIL.
    
    DATA DIVISION.
       LINKAGE SECTION.
       01 LS-STUDENT-ID PIC 9(4).
       01 LS-STUDENT-NAME PIC A(15).
    
    PROCEDURE DIVISION USING LS-STUDENT-ID, LS-STUDENT-NAME.
       DISPLAY 'In Called Program'.
       MOVE 1111 TO LS-STUDENT-ID.
    EXIT PROGRAM.

    JCL to execute the above COBOL program −

    //SAMPLE JOB(TESTJCL,XXXXXX),CLASS = A,MSGCLASS = C
    //STEP1 EXEC PGM = MAIN

    When you compile and execute the above program, it produces the following result −

    In Called Program
    Student Id : 1111
    Student Name : Tim
    

    Call By Content

    If the values of variables in the called program are modified, then their new values will not reflect in the calling program.

    Syntax

    Following is the syntax of calling subroutine by content −

    CALL sub-prog-name USING 
    BY CONTENT variable-1, BY CONTENT variable-2.
    

    Example

    Following example is the MAIN calling program and UTIL is the called program −

    IDENTIFICATION DIVISION.
    PROGRAM-ID. MAIN.
    
    DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-STUDENT-ID PIC 9(4) VALUE 1000.
       01 WS-STUDENT-NAME PIC A(15) VALUE 'Tim'.
    
    PROCEDURE DIVISION.
       CALL 'UTIL' USING BY CONTENT WS-STUDENT-ID, BY CONTENT WS-STUDENT-NAME.
       DISPLAY 'Student Id : ' WS-STUDENT-ID
       DISPLAY 'Student Name : ' WS-STUDENT-NAME
    STOP RUN.

    Called Program

    IDENTIFICATION DIVISION.
    PROGRAM-ID. UTIL.
    
    DATA DIVISION.
       LINKAGE SECTION.
       01 LS-STUDENT-ID PIC 9(4).
       01 LS-STUDENT-NAME PIC A(15).
    
    PROCEDURE DIVISION USING LS-STUDENT-ID, LS-STUDENT-NAME.
       DISPLAY 'In Called Program'.
       MOVE 1111 TO LS-STUDENT-ID.
    EXIT PROGRAM.

    JCL to execute the above COBOL program −

    //SAMPLE JOB(TESTJCL,XXXXXX),CLASS = A,MSGCLASS = C
    //STEP1 EXEC PGM = MAIN

    When you compile and execute the above program, it produces the following result −

    In Called Program
    Student Id : 1000
    Student Name : Tim
    

    Types of Call

    There are two types of calls −

    • Static Call occurs when a program is compiled with the NODYNAM compiler option. A static called program is loaded into storage at compile time.
    • Dynamic Call occurs when a program is compiled with the DYNAM and NODLL compiler option. A dynamic called program is loaded into storage at runtime.
  • File Access Mode

    Till now, file organization schemes have been discussed. For each file organization scheme, different access modes can be used. Following are the types of file access modes −

    • Sequential Access
    • Random Access
    • Dynamic Access

    The syntaxes in this module, mentioned along with their respective terms, only refer to their usage in the program. The complete programs using these syntaxes would be discussed in the next chapter.

    Sequential Access

    When the access mode is sequential, the method of record retrieval changes as per the selected file organization.

    • For sequential files, records are accessed in the same order in which they were inserted.
    • For indexed files, the parameter used to fetch the records are the record key values.
    • For relative files, relative record keys are used to retrieve the records.

    Syntax

    Following is the syntax of sequential access mode −

    ENVIRONMENT DIVISION.
    INPUT-OUTPUT SECTION.
    FILE-CONTROL.
       SELECT file-name ASSIGN TO dd-name
       ORGANIZATION IS SEQUENTIAL
       ACCESS MODE IS SEQUENTIAL
    	
    	
    ENVIRONMENT DIVISION.
    INPUT-OUTPUT SECTION.
       FILE-CONTROL.
       SELECT file-name ASSIGN TO dd-name
       ORGANIZATION IS INDEXED
       ACCESS MODE IS SEQUENTIAL
       RECORD KEY IS rec-key1
       ALTERNATE RECORD KEY IS rec-key2
    
    		
    ENVIRONMENT DIVISION.
    INPUT-OUTPUT SECTION.
       FILE-CONTROL.
       SELECT file-name ASSIGN TO dd-name
       ORGANIZATION IS RELATIVE
       ACCESS MODE IS SEQUENTIAL
       RELATIVE KEY IS rec-key1
    

    Random Access

    When the access mode is RANDOM, the method of record retrieval changes as per the selected file organization.

    • For indexed files, records are accessed according to the value placed in a key field which can be primary or alternate key. There can be one or more alternate indexes.
    • For relative files , records are retrieved through relative record keys.

    Syntax

    Following is the syntax of random access mode −

    ENVIRONMENT DIVISION.
    INPUT-OUTPUT SECTION.
       FILE-CONTROL.
       SELECT file-name ASSIGN TO dd-name
       ORGANIZATION IS INDEXED
       ACCESS MODE IS RANDOM
       RECORD KEY IS rec-key1
       ALTERNATE RECORD KEY IS rec-key2
    
    		
    ENVIRONMENT DIVISION.
    INPUT-OUTPUT SECTION.
       FILE-CONTROL.
       SELECT file-name ASSIGN TO dd-name
       ORGANIZATION IS RELATIVE
       ACCESS MODE IS RANDOM
       RELATIVE KEY IS rec-key1
    

    Dynamic Access

    Dynamic access supports both sequential and random access in the same program. With dynamic access, one file definition is used to perform both sequential and random processing like accessing some records in sequential order and other records by their keys.

    With relative and indexed files, the dynamic access mode allows you to switch back and forth between sequential access mode and random access mode while reading a file by using the NEXT phrase on the READ statement. NEXT and READ functionalities will be discussed in the next chapter.

    Syntax

    Following is the syntax of dynamic access mode −

    ENVIRONMENT DIVISION.
    INPUT-OUTPUT SECTION.
       FILE-CONTROL.
       SELECT file-name ASSIGN TO dd-name
       ORGANIZATION IS SEQUENTIAL
       ACCESS MODE IS DYNAMIC
       RECORD KEY IS rec-key1
       ALTERNATE RECORD KEY IS rec-key2
    
    		
    ENVIRONMENT DIVISION.
    INPUT-OUTPUT SECTION.
       FILE-CONTROL.
       SELECT file-name ASSIGN TO dd-name
       ORGANIZATION IS RELATIVE
       ACCESS MODE IS DYNAMIC
       RELATIVE KEY IS rec-key1
    
  • File Organization

    File organization indicates how the records are organized in a file. There are different types of organizations for files so as to increase their efficiency of accessing the records. Following are the types of file organization schemes −

    • Sequential file organization
    • Indexed sequential file organization
    • Relative file organization

    The syntaxes in this module, mentioned along with their respective terms, only refer to their usage in the program. The complete programs using these syntaxes would be discussed in the chapter ‘File handling Verbs’.

    Sequential File Organization

    A sequential file consists of records that are stored and accessed in sequential order. Following are the key attributes of sequential file organization −

    • Records can be read in sequential order. For reading the 10th record, all the previous 9 records should be read.
    • Records are written in sequential order. A new record cannot be inserted in between. A new record is always inserted at the end of the file.
    • After placing a record into a sequential file, it is not possible to delete, shorten, or lengthen a record.
    • Order of the records, once inserted, can never be changed.
    • Updation of record is possible. A record can be overwritten, if the new record length is same as the old record length.
    • Sequential output files are good option for printing.

    Syntax

    Following is the syntax of sequential file organization −

    INPUT-OUTPUT SECTION.
    FILE-CONTROL.
       SELECT file-name ASSIGN TO dd-name-jcl
       ORGANIZATION IS SEQUENTIAL
    

    Indexed Sequential File Organization

    An indexed sequential file consists of records that can be accessed sequentially. Direct access is also possible. It consists of two parts −

    • Data File contains records in sequential scheme.
    • Index File contains the primary key and its address in the data file.

    Following are the key attributes of sequential file organization −

    • Records can be read in sequential order just like in sequential file organization.
    • Records can be accessed randomly if the primary key is known. Index file is used to get the address of a record and then the record is fetched from the data file.
    • Sorted index is maintained in this file system which relates the key value to the position of the record in the file.
    • Alternate index can also be created to fetch the records.

    Syntax

    Following is the syntax of indexed sequential file organization −

    INPUT-OUTPUT SECTION.
    FILE-CONTROL.
       SELECT file-name ASSIGN TO dd-name-jcl
       ORGANIZATION IS INDEXED
       RECORD KEY IS primary-key
       ALTERNATE RECORD KEY IS rec-key

    Relative File Organization

    A relative file consists of records ordered by their relative address. Following are the key attributes of relative file organization −

    • Records can be read in sequential order just like in sequential and indexed file organization.
    • Records can be accessed using relative key. Relative key represents the record’s location relative to the address of the start of the file.
    • Records can be inserted using relative key. Relative address is calculated using relative key.
    • Relative file provides the fastest access to the records.
    • The main disadvantage of this file system is that if some intermediate records are missing, they will also occupy space.

    Syntax

    Following is the syntax of relative file organization −

    INPUT-OUTPUT SECTION.
    FILE-CONTROL.
       SELECT file-name ASSIGN TO dd-name-jcl
       ORGANIZATION IS RELATIVE
       RELATIVE KEY IS rec-key