-2

I've got the following two dimensional array of ASCII characters:

1st row: a(1,1)=A, a(1,2)=B, a(1,3)=C, a(1,4)=D, ...
2nd row: a(2,1)=a, a(2,2)=b, a(2,3)=c, a(2,4)=d, ...
3rd row: a(3,1)=!, a(3,2)=", a(3,3)=#, a(3,4)=$, ...
...

For further processing, I would like to pack them into a one dimensional array elements as follows:

b(1)<=a(1,:)=ABCD...,
b(2)<=a(2,:)=abcd...,
b(3)<=a(3,:)=!"#$...,
...

It cannot go directly like this because arrays b(:) and a(:,:) are of different types

In particular, I would like have to some suggestions for --???--> for the do loop below

do j=1,n
   if (some condition) then
   a(:,j) --???--> b(j)
   end if
end do

(b(j) might by a blank (" ", ASCII 32), provided a condition excludes it.)

I can easily print out the strings as follows

do j=1,n
  if (condition which excludes the 2nd row) then
     print *, a(j,:)
  end if
end do

The output is:

ABCD...
!"#$...
.......

but that is not what I need. What I need is b(j) for further processing.

Fvwm
  • 1
  • 2
  • 2
    Post code, not *kind-of-like code*. Show us your original array declarations, and the target array declarations, and explain clearly how you want to transform the former to the latter. Right now, it's too difficult to try to figure out what you are asking. – High Performance Mark Jul 26 '20 at 20:55
  • Do you want to create a new 1D array by concatenating all the characters from each row of the original 2D array? – Matt P Jul 26 '20 at 21:33
  • -> Matt P. Yes, that is exactly what I want. – Fvwm Jul 26 '20 at 22:07
  • 1
    would this page help you: http://fortranwiki.org/fortran/show/String_Functions – kvantour Jul 27 '20 at 12:35

1 Answers1

-1

Do you mean something like this

program bah
   implicit none
   character a(3,4)
   character(len=:), allocatable :: b(:)
   integer i, j
   a = reshape(['1','2','3','4','5','6','7','8','9','0','a','b'], [3,4])
   print '(4A2)', a(1,:)
   print '(4A2)', a(2,:)
   print '(4A2)', a(3,:)
   allocate(character(len=size(a(1,:))) :: b(size(a(:,1))))
   do i = 1, size(a(:,1))
      do j = 1, size(a(1,:))
         b(i)(j:j) = a(i,j)
      end do
   end do
   print *, trim(b(1))
   print *, trim(b(2))
   print *, trim(b(3))
end program bah
Ian Bush
  • 6,996
  • 1
  • 21
  • 27
evets
  • 996
  • 1
  • 5
  • 6
  • 1
    Expressions such as `size(a(1,:))` can also be written as `size(a,2)`. – High Performance Mark Jul 27 '20 at 07:46
  • High Performance Mark is right. I should have given the whole code but it is difficult to extract it from my program which has got over 1000 lines. The problem is that a(i,j) have other values (dots above) and double do-loops do not work for those. What I would like to obtain is a(:,j) --> b(j), i.e., to somehow go around "Error: Incompatible ranks 0 and 1 in assignment", i.e., to directly map the whole rows a(:,j) to the columns of b(j) and not via explicit "i" from a(i,j). Is there any trick in Fortran to treat the whole rows of a 2dim array as elements of an 1dim array? – Fvwm Jul 27 '20 at 14:17
  • The answer given in https://stackoverflow.com/questions/37980442/how-to-pass-character-array-into-string is essentially of the same kind as the answer given here. They both rely on double do loops and that is of no help in the given problem because elements of a(i,j) are being processed (together with the size of rows and columns) and depend on other variables of the program. These other variables determine which row of a(i,j) should be mapped to b(j) but do not specify "i" so the rows should be treated as single strings, i.e., we should have a(:,j) -> b(j). – Fvwm Jul 27 '20 at 15:03
  • 1
    If you want anyone to read your extensive commentary edit the material into your question. You may convince someone that it is not a duplicate of the one identified, and prompt votes to re-open. But trying to decipher comments is too difficult. – High Performance Mark Jul 27 '20 at 15:20
  • Second Mark's comment. I have no idea why do loops don't address what you are trying to achieve. The example program provided by evets seems to do exactly what you want, as you say in the reply to the comment by Matt P. – Ian Bush Jul 27 '20 at 15:26
  • 1
    @IanBush, I'm also wondering about the aversion to nested do-loops to do the conversion. The example program was meant as a teaching tool (including the labeled do statements ;-). It should be trivial to write a function to do `b(j) = smash(a(:,j))`. Here one needs to have the length type parameter of `b` large enough to handle the largest string returned by `smash`, or the result will be truncated on assignment. This would _hide_ the nested loops. – evets Jul 27 '20 at 16:05
  • OK, I tweaked my a(i,j) array and the answer "bah" applies. In effect, this does give a mapping a(:,j) -> b(j). Thanks. – Fvwm Jul 27 '20 at 22:47