Fortran

Guide To Learn

Let’s start with the simplest I/O imaginable. In this subsection, we’ll program a simple robot called Echo. This robot can’t do many things. He can’t move, ask questions, or even think. In fact, Echo can do only two things–listen to what we say, and say it back to us. This is actually more powerful than it seems at first. Echo can hear us, and he can also speak. He doesn’t seem to do much internally with what we tell him, but let’s worry about that later. The important part for now is that we can communicate with Echo.

To make Echo the robot, we’ll write a program that will receive our input from the keyboard and emit that data to the screen. If you’re familiar with Linux command-line tools, this functionality is similar to that of tee, a GNU core utility. The program should work like this: when invoked, it will wait for the user to enter some message into the terminal. Once received, the program will print the same message to the screen, as shown in the following listing.

Listing 6.1 Compiling and running your first I/O program

gfortran echo_robot.f90 -o echo_robot    ❶
./echo_robot                             ❷
Greetings!                               ❸
 Greetings!                              ❹

❶ Compiles the program into an executable with the same name

❷ Runs the program

❸ This line is input by the user.

❹ This line is output by the program.

The first output of the message (“Greetings!”) isn’t output by the program, but is typed in by the user and emitted to the terminal at the same time. Only after the user presses the Enter key will the program read this message and write it back to the screen. The message thus appears twice.

To accomplish this task, we’ll engage the read and print statements in their basic form. The following listing provides the complete program.

Listing 6.2 Reading user input from the keyboard and writing it to the screen

program echo_robot
  implicit none
  character(len=1000) :: text     ❶
  read *, text                    ❷
  print *, trim(text)             ❸
end program echo_robot

❶ 1,000-character string to store user input

❷ Reads user input and stores it into the variable

❸ Trims the message to remove trailing blanks and writes it to the screen

This program consists of essentially three statements: one declaration and two built-in I/O statements. We first declare a character string text that will hold the data input from the keyboard. Recall that when declaring a character variable, we need to give it a fixed length a priori, or declare it as a dynamic (allocatable) string. While using the allocatable string would be a more elegant solution here, it would complicate the code quite a bit because Fortran doesn’t allow us to automatically allocate a string on a read statement. Instead, we’d need to somehow find out the length of the input, allocate the string, and then use the read statement to store the data into the variable. To keep this example simple, we’ll stick with a fixed-length string. There’s nothing special about the number 1000 here–we’re just making this character variable long enough to hold an unusually large text input. The first I/O statement is read *, text. It instructs the computer to read the data from the standard input (more on this in a bit), using default formatting (*), and store it into text. The second I/O statement, print *, trim(text), does the same, but the other way around. It takes the value of trim(text) and prints it to the screen (terminal) using default formatting (*).

trim is the built-in function that removes any trailing blanks. It takes care of the fact that text is 1,000 characters long, and anything beyond the text input by the user is padded by spaces. What would happen if we didn’t do this? Since text is declared as character(len=1000), only the first 10 characters will be occupied by “Greetings!”, and the rest will remain blank. Trimming the blank characters off the end of message will thus make the output not spill over into the next line if our terminal screen is less than 1,000 characters wide (mine is 80).

Removing trailing blanks from character strings

If your character variable is longer than the data you assign to it, like it is in listing 6.2, the unused part of the variable will always be padded by spaces. Use the built-in function trim whenever you need to remove such trailing spaces on the fly. For example, trim('run-017.dat ') returns just 'run-017.dat'. This is useful in any situation in which you can’t predict the length of the string you’re working with; for example, a user inputting the name of the file to be read by the program.

Compile and run this program a few times. Play around with it. Does it work as expected? Almost, but not quite:

./echo_robot
Hello!
 Hello!         ❶

❶ Leading space in the output that I didn’t ask for

This is what I expected, except for that one little pesky space in front of the output. OK, I can swallow this. But it gets worse:

./echo_robot
Hi, there, Echo! :)
 Hi
./echo_robot
Wait, what just happened?
 Wait

Oh no! Now whole parts of my input are gone–our poor robot is broken. This is not at all what we intended. What’s going on here? Based on our experiments so far, the program seems to read input only up to a comma and writes a spurious leading space in the output.

It turns out that the culprit is the default formatting, specified by the asterisk (*) in the read and print statements. This is also what’s known in the Fortran lingo as list-directed I/O, which allows you to read or write multiple variables on the same line, separated by spaces or commas. It’s a feature, not a bug! When we use default formatting and try to enter a message with spaces or commas in it, the program will interpret these as separate variables. However, we provide only one variable on the right side of the read statement, so the rest of the message is discarded. Fortunately, there’s an easy fix, and that is to specify a text formatting string in place of the asterisk:

read '(a)', text           ❶
print '(a)', trim(text)    ❷

❶ Reads text from the keyboard using text formatting

❷ Writes trim(text) to the screen using text formatting

Immediately after typing read, we provide the format string for text data ('(a)'). This statement will thus read any data that’s input on the keyboard, format it with '(a)', and print it to the screen.

The formatting strings are instructions for the program on how to format data. We’ll get into the specifics of number and text formatting soon. For now, all you need to know is that you can use '(a)' as a format string to read data as character strings, no matter if the data is plain text or numbers.

This program is not terribly useful in the real world, but it illustrates how read and print statements work in their most basic form.

Passing data from other programs

Typing the data using the keyboard isn’t the only way to get data into the program through standard input. For example, with the bash shell on Linux or macOS, you could also input data straight from the command line when executing the program

./echo_robot <<< "Hi, there, Echo! :)"

or pipe it from another program:

The simplest I/O

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top