# CHARACTER Operator and Substrings

### Concatenation Operator //

Fortran has only one character operator, the concatenation operator //. The concatenation operator cannot be used with arithmetic operators. Given two strings, s1 and s2 of lengths m and n, respectively, the concatenation of s1 and s2, written as s1 // s2, contains all characters in string s1, followed by all characters in string s2. Therefore, the length of s1 // s2 is m+n.

Consider the following statements:

```CHARACTER(LEN=4)   :: John = "John", Sam    = "Sam"
CHARACTER(LEN=6)   :: Lori = "Lori", Reagan = "Reagan"
CHARACTER(LEN=10)  :: Ans1, Ans2, Ans3, Ans4

Ans1 = John // Lori
Ans2 = Sam  // Reagon
Ans3 = Reagon // Sam
Ans4 = Lori // Sam
```
• Variable Ans1 contains a string "JohnLori**", where * denotes a space. These two spaces come from variable Lori since its content is "Lori**".
• Variable Ans2 contains a string "Sam Reagan". The space in the string comes from variable Sam since its content is "Sam*", where, as above, * denotes a space.
• Variable Ans3 contains a string "ReaganSam*".
• Variable Ans4 contains a string "Lori**Sam*".

### Substrings

A consecutive part of a string is called a substring. One can append the extent specifier at the end of a CHARACTER variable to indicate a substring. An extent specifier has a form of
```( integer-exp1 : integer-exp2 )
```
It starts with a (, followed by an integer expression, followed by a colon :, followed by another integer expression, followed by ). The first integer indicates the first position of the substring, while the second integer indicates the last position of the substring. Therefore, (3:5) means the substring consists of the third, fourth and fifth characters. If the content of variable String is "abcdefghijk", then String(3:5) is a string "cde".

If the first integer expression is missing, the value is assumed to be 1. If the second integer expression is missing, the value is assumed to be the last character of the string. Continue with the example in previous paragraph. String(:4) is string "abcd". String(2+5:) is string "ghijk".

As a good programming practice, the value of the first integer expression should be greater than or equal to 1, and the value of the second integer expression should be less than of equal to the length of the string.

A string variable with an extent specifier can be used on the left-hand side of an assignment. Its meaning is assigning the string content on the right-hand side into the substring part of the string variable. Let the content of a string variable LeftHand of length 10 be "1234567890". The following are a few examples:

• LeftHand(3:5) = "abc": the new content of LeftHand is "12abc67890".
• LeftHand(1:6) = "uvwxyz": the new content of LeftHand is "uvwxyz7890".
• LeftHand(:6) = "uvzxyz": the result is identical to the previous example.
• LeftHand(4:) = "lmnopqr": the new content of LeftHand is "123lmnopqr".
• LeftHand(3:8) = "abc": the new content of LeftHand is "12abc***90", where * denotes a space. Note that since LeftHand(3:8) consists of 6 character positions and "abc" has only three characters, the remaining will be filled with spaces.
• LeftHand(4:7) = "lmnopq": the new content of LeftHand is "123lmno890". It is due to truncation.

### Example

```! ----------------------------------------------------------------
!  This program uses DATE_AND_TIME() to retrieve the system date
!  and the system time.  Then, it converts the date and time
!  information to a readable format.  This program demonstrates
!  the use of concatenation operator // and substring
! ----------------------------------------------------------------

PROGRAM  DateTime
IMPLICIT   NONE

CHARACTER(LEN = 8)  :: DateINFO                 ! ccyymmdd
CHARACTER(LEN = 4)  :: Year, Month*2, Day*2

CHARACTER(LEN = 10) :: TimeINFO, PrettyTime*12  ! hhmmss.sss
CHARACTER(LEN = 2)  :: Hour, Minute, Second*6

CALL  DATE_AND_TIME(DateINFO, TimeINFO)

!  decompose DateINFO into year, month and day.
!  DateINFO has a form of ccyymmdd, where cc = century, yy = year
!  mm = month and dd = day

Year  = DateINFO(1:4)
Month = DateINFO(5:6)
Day   = DateINFO(7:8)

WRITE(*,*)  'Date information -> ', DateINFO
WRITE(*,*)  '            Year -> ', Year
WRITE(*,*)  '           Month -> ', Month
WRITE(*,*)  '             Day -> ', Day

!  decompose TimeINFO into hour, minute and second.
!  TimeINFO has a form of hhmmss.sss, where h = hour, m = minute
!  and s = second

Hour   = TimeINFO(1:2)
Minute = TimeINFO(3:4)
Second = TimeINFO(5:10)

PrettyTime = Hour // ':' // Minute // ':' // Second

WRITE(*,*)
WRITE(*,*)  'Time Information -> ', TimeINFO
WRITE(*,*)  '            Hour -> ', Hour
WRITE(*,*)  '          Minite -> ', Minute
WRITE(*,*)  '          Second -> ', Second
WRITE(*,*)  '     Pretty Time -> ', PrettyTime

!  the substring operator can be used on the left-hand side.

PrettyTime = ' '
PrettyTime( :2) = Hour
PrettyTime(3:3) = ':'
PrettyTime(4:5) = Minute
PrettyTime(6:6) = ':'
PrettyTime(7: ) = Second

WRITE(*,*)
WRITE(*,*)  '     Pretty Time -> ', PrettyTime

END PROGRAM  DateTime
```

### Program Output

```Date information -> 19970811
Year -> 1997
Month -> 08
Day -> 11

Time Information -> 010717.620
Hour -> 01
Minite -> 07
Second -> 17.620
Pretty Time -> 01:07:17.620

Pretty Time -> 01:07:17.620
```

### Discussion

• Subroutine DATE_AND_TIME() returns the date of time and day information into two character arguments. The first one, DateINFO, must have a length of at least 8. The returned value is in the form of ccyymmdd, where cc gives the century, yy the year, mm the month, and dd the day. If today is August 11, 1997, the call to this subroutine returns a string of eight characters "19970811"
• The second argument, TimeINFO, will receive a string of 12 characters with a form of hhmmss.sss, where hh gives the hour value, mm the minute value, and ss.sss the second value. Thus, if the time this subroutine is called is 1 after 7 minutes and 17.620 seconds, the returned value is "010717.620"