2

Suppose I have a Fortran program like the following:

      character*30 changed_string1
      changed_string1="hello"
      write(*,"(A)")changed_string1(1:3)
      end

I would like to print the string with quotes so that I can exactly see leading and trailing spaces. How to do this?

francescalus
  • 30,576
  • 16
  • 61
  • 96
wander95
  • 1,298
  • 1
  • 15
  • 22
  • What do you means by "exactly see leading and trailing spaces"? Do you really need the ancient Fortran 77? Why on earth? – Vladimir F Героям слава Aug 10 '21 at 15:06
  • I need to see spaces for some debugging purposes that are tangential to the question and irrelevant to the question. I could mix in Fortran90 if needed. – wander95 Aug 10 '21 at 15:10
  • This is a completely different question. The question is not about differences between quotes but escaping it in a certain character to see its length by manually counting – wander95 Aug 10 '21 at 15:16
  • This question is essentially "how do I print quote characters?". One of the main reasons to decide between quotes and apostrophes for character delimiting is precisely to allow "nice" printing of quotes. – francescalus Aug 10 '21 at 15:18
  • No this isn't about nice printing of quotes. That can be done by `"'"`. – wander95 Aug 10 '21 at 15:25
  • BTW you are already using Fortran90 or later - " was not part of the (now deleted) Fortran 77 standard character set – Ian Bush Aug 10 '21 at 15:27
  • removed the fortran77 tag and requirement – wander95 Aug 10 '21 at 15:33
  • If you know how to print quote characters, then can you clarify what it is you don't know? Is it how to get automatically get delimiters in there? – francescalus Aug 10 '21 at 15:33

2 Answers2

7

There is no edit descriptor for characters which outputs them along with delimiters. A character variable does not have "automatic" delimiters like those which appear in a literal character constant (although may have them as content).

Which means you have to explicitly print any chosen delimiter yourself, adding them to the format or concatenating as in Vladimir F's answer.

Similarly, you can also add the delimiters to the output list (with corresponding format change):

write (*,'(3A)') '"', string, '"'

You can even write a function which returns a "delimited string" and use the result in the output list:

  implicit none

  character(50) :: string="hello"
  print '(A)', delimit(string,'"')

contains

  pure function delimit(str, delim) result(delimited)
    character(*), intent(in) :: str, delim
    character(len(str)+2*len(delim)) delimited

    delimited = delim//str//delim
  end function delimit

end program

The function result above could even be deferred length (character(:), allocatable :: delimited) to avoid the explicit statement of result length.


As yamajun reminds us in a comment, a connection for formatted output has a delimiter mode, which does allow quotes and apostrophes to be added automatically to the output for list-directed and namelist output (only). For example, we can control the delimiter mode for a particular data transfer statement:

write(*, *, delim='quote') string
write(*, *, delim='apostrophe') string

or for the connection as a whole:

open(unit=output_unit, delim='quote')  ! output_unit from module iso_fortan_env

Don't forget that list-directed output will add that leading blank to your output, and if you have quotes or apostrophes in your character output item you will not see exactly the same representation (this could even be what you want):

use, intrinsic :: iso_fortran_env, only : output_unit
open(output_unit, delim='apostrophe')

print*, "Don't be surprised by this output"

end

Fortran 2018 doesn't allow arbitrary delimiter choice in this way, but this could still be suitable for some uses.

francescalus
  • 30,576
  • 16
  • 61
  • 96
  • Will Fortran ever have variable length strings, which would allow not to _have to_ specify the string length beforehand in such scenario. The statement `delimited = delim//str//delim` should be enough for the compiler to know the length of `delimited`. – JAlex Aug 10 '21 at 19:43
  • 1
    @JAlex Fortran has been having deferred-length strings for many years. – Vladimir F Героям слава Aug 10 '21 at 21:24
  • 1
    @JAlex, `character(:), allocatable :: delimited` suits that. – francescalus Aug 10 '21 at 21:37
  • 1
    By reopening standard output unit with delimiter option, list-directed character output can be quoted. use, intrinsic :: iso_fortran_env open(unit=output_unit, delim='quote') print *, 'hello' – yamajun Aug 11 '21 at 14:24
  • 1
    @yamajun, I had neglected list-directed output, but that's certainly worth mentioning, thanks. – francescalus Aug 11 '21 at 14:51
4

You can print quotes around your string. That will enable see the leading and trailing spaces.

write(*,"('''',A,'''')") changed_string1

or with the same effect

write(*,"(3A)") "'",changed_string1,"'"

(also mentioned by francescalus) that print a ' character before and afgter your string,

or you can concatenate your string with these characters and print the result

write(*,"(A)") "'"//changed_string1//"'"