How do I read an input in Fortran without interrupting the program? - fortran

An usual read statement in Fortran interrupts the execution of the program until the RETURN key was pressed. I am looking for a statement that reads any pressed key without waiting for the RETURN key. The program should not stop even if no key was pressed.
Thank you for your answer.
Edit:
Here is some source code that should clarify the question.
Program test1
n=2
do while (n==2)
read (*,*) n
write (*,*) 'Output'
end do
end program test1
Program test2
n=2
do while (n==2)
UnknownReadStatement (*,*) n
write (*,*) 'Output'
end do
end program test2
The program test1 will never write the word "Output" on the screen if no key is pressed.
Using the read statement I am looking for the program test2 should fill the screen with "Output" until a key different from "2" is pressed.

There is an example code for reading a single key from the terminal from Fortran without requiring that the input be terminated by a return key at http://home.comcast.net/~urbanjost/CLONE/GETKEY/getkey.html. I haven't tried this code, so can't vouch for it. His (John Ubran) solution mixes Fortran and C, using the C getkey. Assuming that your compiler supports it (most do), I suggest trying the ISO_C_BINDING method to combine the Fortran and C. This doesn't answer the part about the program proceeding even if no key is pressed -- for that you will have to add some sort of timeout, to give the person a chance to type something, but to timeout and proceed if they don't type by a deadline. Maybe you can modify the solution I linked to...

Related

Create list from input using interact in Haskell

I'm starting out with Haskell and was looking into I/O mechanims. I read up on the interact function which takes a function of type String -> String as parameter. I tried to write a simple program that takes to numbers from stdin and creates a list and prints it line by line.
import Data.List
readIn = sort . map read . words
writeOut = unlines . map show
rangeList [n,m] = [n .. m]
main = interact (writeOut . rangeList . readIn)
For some reason it wont print the numbers. Could you help me out?
interact requires you to input an end-of-file (EOF) to stdin with Ctrl+D (or Ctrl+Z on Windows); when I type that combination, the output appears as required. This is necessary because, as the documentation for interact states, ‘the entire input from the standard input device is passed to [interact] as its argument’; due to this, you need to explicitly signal the place where stdin ends.
(By the way, I’m not even sure how you got your program to compile; GHC gives me lots of ‘ambiguous type’ errors when I try. I had to add type signatures to get it working, at which point I found the solution above to work.)

How to let gnuplot window persist and the main program not freeze

I have a program in Fortran that calculates a file, say, named
wvfunc3d.dat
which I want to visualize with Gnuplot in real time during the execution of my program. After the code that creates this file, I put in my program a string
jret=SYSTEM('gnuplot wf3d.plt')
the script file wf3d.plt has the only string and looks like:
splot 'wvfunc3d.dat' w l
All of this really draws a plot I want to see, but, as is well known, it immediately disappears. I know, there is an option to avoid the closing of the window,
jret=SYSTEM('gnuplot -persist wf3d.plt')
that lets my plot not to disappear, but then the execution of the Fortran program also freezes until I close the window with the graph.
So, I want the plot to persist until I have new data, to be automatically updated after a new call of a command in Fortran, but I also need my program to run calculations! Is there a way to solve this problem? I use Windows XP.
I think you may be able to use EXECUTE_COMMAND_LINE instead of system to achieve what you want. This allows you to include a wait option which when set to .false. allows the fortran code to keep running. You can then add a sleep and reread to your gnuplot script (e.g. sleep 1 and reread) as suggested in this post.
If this doesn't work, you could consider a multi-threaded strategy ( openMP or mpi in fortran). Personally, I usually just run gnuplot at the same time and trigger an update of the plotted data by pressing the a key. I use linux so cannot test it for windows but a minimal example which works for me is,
program gnuplot
implicit none
logical :: gnuplot_open = .false.
integer :: i,t,N,redraw
real(kind(0.d0)),dimension(:),allocatable :: x,y
real(kind(0.d0)),parameter:: pi=4.d0*atan(1.d0)
N = 1000
allocate(x(N),y(N))
redraw = 100
do t = 1,300000
do i=1,N
x(i) = 6.d0*i/N*pi
y(i) = sin(x(i)+t*0.2)
enddo
if (mod(t,redraw) .eq. 0) then
open(1,FILE='./tempout',status='replace')
do i=1,N
write(1,*) x(i),y(i)
enddo
close(1,status='keep')
endif
if (.not. gnuplot_open) then
call execute_command_line('gnuplot --persist plot_tempout', wait=.false.)
gnuplot_open = .true.
endif
enddo
end program gnuplot
and plot_tempout is,
plot 'tempout' u 1:2 w l
pause 0.1
reread
Ed, thank you very much for your thorough reply. I will try to work on it.
Before encountering this problem I was able to easily draw the plots of small enough files using a cycle directly in gnuplot. Something like this:
do for [i=1:100500] {plot 'littldat.dat' w l; pause 3}
that did it well. But when I tried to do this with large file, it was very often caught read by gnuplot in the moment it was not completed yet: I had either a full plot or a plot of a part of my data, and it was not good. Because of this I began to seek for the way to do it by the means of programming language.
Before you answered I finally found a very simply, though not very elegant solution: you write data to a temporary file and then, once it is completed, give it the final name to be read by gnuplot. So, gnuplot reads either old data, or new ones, but never an incomplete file. It results to be something like this in Fortran:
open(1,file='donnees_temp.dat')
write(1,*)x,y,z
close(1)
call rename ('donnees_temp.dat','donnees.dat')
and, in Gnuplot I used a cycle like the one above:
do for [i=1:100500] {splot 'donnees.dat' w l; pause 5}
so it works, and the program executes.

How Ctrl Z works actually

Just for curious mind. During problem solving many question says,"Input will be terminated by Ctrl+z". I know its "EOF(End Of File)" But...
while(scanf("%d",&a)==1)
{ cout<<"OK"<<endl;}
while(scanf("%d",&a)!=EOF)
{cout<<"OK"<<endl;}
while(cin>>a)
{cout<<"OK"<<endl;}
Above 3 will be terminated by Ctrl+z.
while(scanf("%d",&a))
{cout<<"OK"<<endl;}
It will give OK by pressing Ctrl+z.
and
while(1){cin>>a;
cout<<"OK"<<endl;}
Its a infinte loop.
I want to know how Ctrl+z works on a program termination. What is the reason behind it. Please answer in details.
Ctrl+z does not terminate your program. It also doesn't pause its execution. It's a 0x1A byte that is interpreted by iostream and stdio methods to be EOF (end-of-file). After that character is read from the console, nothing is read further and the method that is reading it returns. In the case of iostream, std::ios::eof() becomes true.
You would notice in your last case that if you structured it as:
while(cin >> a) { ... }
It would exit like the others.

C++ Primer 1.4.4 — Importance of EOF and how to write in a code that will end without EOF?

Referring to two questions:
Incorrect output from C++ Primer 1.4.4
Confused by control flow execution in C++ Primer example
My question is answered in both of those posts, but I want to delve further.
First, I know this is only the beginning, but let's say I make a fully functional program that runs in a designed window. By that level, will I already know how to implement a EOF? I can't expect someone running my program to know that they need to hit Control-Z.
Is there a way to implement a specific code that functions so that it does not need me to type in an unrecognized value?
Also one guy in those questions somewhat answered the importance of EOF, but how come the program doesn't even post the final cnt - 1?
Let's say I do the numbers 10 10 10 20 20 20. Without EOF, this will only show the "10 repeats 3 times." How come the program doesn't at least type in the count "10 repeats 3 times and 20 repeats 2 times" minus the final one with white space?
lets say I make a fully functional program that runs in a designed window. By that level, will I already know how to implement a eof? I can't expect someone running my program to know that they need to hit ctrl + z.
You could either tell the user explicitly to do a specific action to end input or the design of the window itself could tell the user the information implicitly. For instance, a dialog box could ask the user to enter input and click an OK button when done.
Is there a way to implement a specific code that functions so that it does not need me to type in an unrecognized value?
It seems like you would rather use a newline character to terminate your input. An example of this usage could be std::getline. Instead of writing
while (std::cin >> val)
you could instead use
std::string line;
if (std::getline(std::cin,line))
and assume that your user's input only consists of one line of values. There are plenty of other ways to similarly achieve this task depending on how you want to constrain the user's input.
Let's say I do the numbers 10 10 10 20 20 20. WIthout eof this will only show the "10 repeats 3 times." How come the program doesn't at least type in the count "10 repeats 3 times and 20 repeats 2 times" minus the final one with white space?
Without the eof your program is still executing the while (std::cin >> val) loop since std::cin >> val has not yet received invalid input.
Since the line
std::cout << currVal << " occurs " << cnt << " times" << std::endl;
occurs after that while loop finishes execution, you don't (yet) see any information about the three 20's in the input.
When you are reading a sequence of inputs you'll need some indication when your down. That could be a sentinel value ("enter 999 to stop reading"; you'd need to detect that while reading), an invalid input ("enter X to stop reading"; when reading an int the value X is illegal and causes the stream to got into failure mode, i.e., have std::ios_base::failbit set), or the more conventional "there isn't anything more to read". For a file, the last conditions is straight forward. When reading data from the console you'll either need to teach people how to terminate the input or you'll need to use a different approach.
If you want to intercept any keypressed and react on them directly you may do so, too. You could, e.g., use ncurses and control your input via that. You could also set the concole to non-buffering (on POSIX systems using tcgetattr() and tcsetattr() to clear the ICANON flag) and deal directly with all key presses to decide whether you want to continue reading or not.
Although I'm certainly up to doing fancy I/O stuff I normally don't bother: users will understand the "end of input" character and just deal with it. That is, my input normally looks something like this:
while (in >> whatever_needs_to_be_read) { ... }
... or, if the input is genuinely line oriented
for (std::string line; std::getline(in, line); ) { ... }
The function doing this input will then be called with a suitable std::istream which may be std::cin although I have typically some way to also read from a file (in addition to the shell-privided input redirection).
BTW, despite some indications in the questions referenced, "EOF" is not a character being read. It is a character entered, though (normally). ... and it is quite conventional to "know" the end of input character (on POSIX systems a ctrl-D and on Windows a ctrl-Z). You can use other indicators, e.g., the "interrupt" (ctrl-C) but that takes more work and doesn't integrate nicely with stream. To use the interrupt chacter you'd need to setup a signal handler for SIGINT and deal with that. One slightly annoying part of doing so is that if you get it wrong you'll need to find a different way to kill the program (e.g. on POSIX using ctrl-Z to put the process to sleep and kill it via a harsher signal).

How to execute a command on the first and only first time entering fortran subroutine?

I wrote a subroutine for a Fortran program and I want to execute a command (delete file in the program directory and open a new one) the first, and only first time, the subroutine is called. I know that I can achieve this by creating some flag outside of the subroutine, in the main program, that I set to false at program startup and then set to true upon entering the subroutine. Then I could use this flag in an if statement to figure if the commands I want to execute on the initial call should be executed or not. But this requires me modifying the existing program and I didn't want to do that if I could avoid it. Is there some other way to do what I want to do?
An example might be:
subroutine test(a)
implicit none
integer, intent(inout) :: a
logical, save :: first_time=.true.
if(first_time) then
first_time=.false.
a = a + 12345
else
a = a - 67890
end if
end subroutine test
How about using some characteristic of the output file to determine whether or not to delete it? Time stamp, file lock, a particular file extension, etc.