1

I was trying to copy contents of a file to a string array and I couldn't manage to fully copy the file (it was only copying the first characters in every line). I feel like something is wrong with my syntax and its possible to do it with character, dimension(:,:) but it worked with character(:), dimension(:).

This doesn't work as expected:

character, allocatable :: list(:,:)
integer :: i, line_count, line_length

open(1, "input.txt", status="old", action="read")

line_count = count_file_lines(1) ! function that returns integer
line_length = longest_line_length(1) ! function that returns integer

allocate(list(line_count, line_length))
do i = 1, line_count
    read(1, *) list(i,:)
end do
close(1)

This works as expected:

character(:), allocatable :: list(:)
integer :: i, line_count, line_length

open(1, "input.txt", status="old", action="read")

line_count = count_file_lines(1) ! function that returns integer
line_length = longest_line_length(1) ! function that returns integer

allocate(character(line_length) :: list(line_count))
do i = 1, line_count
    read(1, *) list(i)
end do
close(1)

I've tried switching indexes in the first example and it still didn't work. I understand that the first example is a rank 2 character array but what is the array in the second example? Maybe they both are the same type of array and I got the indexing wrong for the first one. Can someone clarify this?

Terobero
  • 69
  • 2
  • 6
  • The first snippet is not valid Fortran unless `line_count` and `line_length` have the `allocatable` attribute. It would be better to give complete self-contained example over the **"I remember"** half versions. – evets Dec 03 '20 at 19:18
  • @evets I didn't know they were relevant, I've added the entire code for both. They are integers without allocatable. You say its not valid but the program ran, just not the way I wanted it to. – Terobero Dec 03 '20 at 19:31
  • What does "this does not work" actually mean? This phrase does not say anything useful. Were there any error messages? Or is the program doing something wrong? What exactly? – Vladimir F Героям слава Dec 03 '20 at 19:49
  • In the second example you have an array of character strings https://stackoverflow.com/questions/33415590/difference-between-character10-a-and-character-a10 – Vladimir F Героям слава Dec 03 '20 at 19:51
  • @VladimirF I mean it doesn't give the result I expected, I wrote "it was only copying the first characters in every line" which was for the first example. – Terobero Dec 03 '20 at 19:53
  • It is not valid Fortran. This statement: `allocate(line_count, line_length)` is wrong, so the code simply could not have compiled. – evets Dec 03 '20 at 23:01
  • @evets ah my bad, i forgot to put list, fixed it now. – Terobero Dec 03 '20 at 23:05

1 Answers1

2

In the first example you have a 2D array of single characters, of character strings of size 1. In the other example you have a 1D array of longer character strings. See Difference between "character*10 :: a" and "character :: a(10)" for the difference.

The readstatement regards each of the character in the 2D array as a separate variable it tries to read. That is why it appears storing only the first character each time. The list-directed format * you are using is not good enough for reading a character array.

You can actually read a line to a character array, but you have to read it as an array and use the appropriate format

 read(1, '(*(a))') str(i,:)

You are responsible to make sure that three are enough characters on each line of your file for your arrays.

You must also be careful when printing the content, which you do not show.

Be aware that using unit 1 for your files is poor form. Unit numbers below 10 are often pre-connected by the compiler to standard input, standard output, standard error and possibly other files.