Search code examples
fortrancharactercharacter-arrays

Fortran: convert character array to integer/real


I want to convert a character array in Fortran to a numeric type. I think I should avoid strings (perhaps not?), because these arrays store variable length data (user input).

I have the following code:

IMPLICIT NONE

CHARACTER(LEN=1), ALLOCATABLE :: TOKENS(:, :)
CHARACTER(LEN=1)              :: TEST_STR(80)
INTEGER                       :: I
CHARACTER(LEN=80)             :: INPUT_STR
INTEGER                       :: MYINT

INPUT_STR = '  I am a  test  12  string '
DO I = 1, LEN(INPUT_STR)
   TEST_STR(I) = INPUT_STR(I:I)
END DO

CALL TOKENIZE(TEST_STR, ' ', TOKENS)

PRINT *, "-----------"
INPUT_STR = '15'
PRINT *, INPUT_STR(1:2)
READ(INPUT_STR(1:2), '(I2)') MYINT
PRINT *, MYINT
PRINT *, "-----------"
PRINT *, TOKENS(:, 5)
READ(TOKENS(:, 5), '(I2)') MYINT
PRINT *, MYINT

The output looks like this:

 -----------
 15
          15
 -----------
 12
           1

I have tested separately that the tokenizer presents sane output, which it does. However, it seems that READ(TOKENS(:, 5), '(I2)') MYINT is only reading the first element of TOKENS(:, 5).

As a test, I ran it with READ(TOKENS(1, 5), '(I2)') MYINT and READ(TOKENS(2, 5), '(I2)') MYINT, and it printed 1 and 2 respectively.

Any ideas on how I can get it to read the whole array, rather than just one character at a time?


Solution

  • In this line

      READ(TOKENS(:, 5), '(I2)') MYINT
    

    you try to read from an internal file, which is an array of characters.

    However, Fortran uses one character string for the internal read of each record. Therefore it reads from the first element of your array, which is a character string of length one.

    You need to use strings in this part of the code, not an array ofsingle characters.

    For example, if you could live with a fixed maximum character length, you could use

    CHARACTER(LEN=80), ALLOCATABLE :: TOKENS(:)
    

    You could also use

    CHARACTER(LEN=:), ALLOCATABLE :: TOKENS(:)
    

    to change the character length as needed. However, all characters in this array need to be of the same length anyway.

    The last resort would be to use array of some containers which have an allocatable string component inside, but be aware that gfortran did not support these as of version 4.8 at least.