Fortran Symbol Input in Undefined Length

program Test implicit none character (LEN=100) :: input character (LEN=100) :: output print *,"Please input your message: " read *, input 

For each character I encrypt it in Ceaser Cipher

Calculations

 print *,"This is the output: " write (*,"(2a)") "Message = ", out end program Test 

This does not work completely.

For each input character, I convert it using the modulo (iachar ()) functions. It works before printing, I monitored debugging, encryption is in order. But the problem with the exit is LEN = 100. The do loop will go through 100 times, turning non-existent characters into garbage, crashing the output program with UNDEFINED TYPE.

So, if I enter a "test", it will encrypt CBNC * GARBAGE-TO-100 * and not output. If I define the length as 4 and execute it, it works. but I want to be able to do this without determining the length. How to get around this?

0
source share
3 answers

The read statement should fill input with the entire length of the variable (100 characters) with spaces, and not add garbage. The internal function LEN_TRIM will give a significant length to the value of the variable — that is, the length, excluding trailing spaces. You may need to remember this significant length of the input line when you print the output line.

(Note that the rules for entering a list (indicated by * in the reading instructions) may be a bit surprising - the format "(A)" may be more reliable, depending on your behavior.)

In terms of eliminating fixed-length strings in the context of reading input, Fortran 2003 introduces a delayed-character, which helps a lot here. Otherwise, see Reading a character string of unknown length for Fortran 95 features. One of the complications is that you are reading from the console, so the backspace statement may not work. Work on this follows a similar approach to a related one, but requires a piecewise construction of the input string into a distributed character array at the same time as determining the length of the input record. The Sequence association is then used to transform this array into a scalar of the desired length. Please try again or ask if you would like more information.

+1
source

The following code reads a user input string of indefinite length. Keep in mind that this requires a compiler that supports deferred character(len = :) strings: character(len = :) . Delayed string strings were introduced in Fortran 2003.

 program test use iso_fortran_env, only : IOSTAT_EOR implicit none integer :: io_number character(len = 1) :: buffer character(len = :), allocatable :: input, output input = "" print *, "Please input your message." do read(unit = *, fmt = '(a)', advance = "no", iostat = io_number) buffer select case (io_number) case(0) input = input // buffer case(IOSTAT_EOR) exit end select end do allocate(character(len=(len(input))) :: output) ! Now use "input" and "output" with the ciphering subroutine/function. end program test 

Description

The idea is to read one character at a time, looking for a write termination condition (eor). The eor condition is triggered by pressing the return button. The "iostat" option can be used to search for eor. The value returned by "iostat" is equal to the integer constant "IOSTAT_EOR" located in the iso_fortran_env module:

 use iso_fortran_env, only : IOSTAT_EOR 

We declare a string of characters with a deferred length to capture user input of unknown length:

 character(len = :), allocatable :: input 

In the "read" instruction, advance = "no" allows you to read several characters at a time. The size of the "buffer" determines the number of characters that need to be read (1 in our case).

 read(unit = *, fmt = '(a)', advance = "no", iostat = io_number) buffer 

If "iostat" returns "0", then there were no errors and no. In this case, the character "buffer" should be added to the string "enter". Ultimately, this step allocates a "new" input, the size of which is the "old" input + buffer character. The newly assigned input contains characters from the old input + buffer character.

 select case (io_number) case(0) input = input // buffer 

If "iostat" returns eor, exit the do loop.

 case(IOSTAT_EOR) exit 
+1
source

The standard Fortran line is a fixed length, filled with spaces on the right. If your input line will never have trailing spaces, the solution will be easy: use the built-in Fortran len_trim function to find a non-empty line length and process only those characters. Another approach is to use a new function, allocatable string ..., which provides variable-length strings. If rejecting spaces at the end of a line is acceptable, you will probably find using len_trim easier.

0
source

All Articles