Lazarus

Free Pascal => Beginners => Topic started by: Ludan on September 17, 2022, 01:58:42 pm

Title: Readln not being executed after Read() (Solved)
Post by: Ludan on September 17, 2022, 01:58:42 pm
Hello everyone, first post.
I'm in the process of learning the pascal language with freepascal and encountered some weird behavior (to me) regarding readln() after read()
Was writing a small program to test the case statement, it is about roman digits:

Code: Pascal  [Select][+][-]
  1. Program RomanDigit;
  2. var i : integer;
  3.  
  4. begin
  5.    write('i='); read(i);
  6.    case i of
  7.       1   : writeln('I');
  8.       10   : writeln('X');
  9.       50   : writeln('L');
  10.       100   : writeln('C');
  11.       500   : writeln('D');
  12.       1000 : writeln('M');
  13.    { else writeln('The number entered does not represent a roman digit'); }
  14.    otherwise writeln('The number entered does not represent a roman digit');
  15.    end;
  16.    writeln('Before');
  17.    readln; { don't know why this line is not being executed }
  18.    writeln('After');
  19. end.
  20.  

The last readln is not being executed.

The code works if I use readln(i) instead of read(i).
Also the code works if assign i:=1 (or any other number) instead of reading it from the keyboard.
Added printing 'Before' and 'After' for 'debugging' and they are printed normally, but readln is not being executed.
Maybe this is expected behavior, IDK, I'm still learning.
Any opinion to shed light on this situation is appreciated.
Thanks in advance.
Title: Re: Readln not being executed after Read()
Post by: marcov on September 17, 2022, 02:08:01 pm
That seems normal:

An user enters  number  and presses enter.

The read() reads the number, the readln() reads the enter.
Title: Re: Readln not being executed after Read()
Post by: Ludan on September 17, 2022, 02:17:54 pm
Ah, I see.
It is a bit confusing, was expecting that readln to read the enter after writeln('Before'); and pause.
I guess I have to make use of another readln to pause the execution of the program before it exits, or just use readln(i) in the first place.
Title: Re: Readln not being executed after Read()
Post by: 440bx on September 17, 2022, 02:56:31 pm
or just use readln(i) in the first place.
That one is the simplest.
Title: Re: Readln not being executed after Read() (Solved)
Post by: VisualLab on September 17, 2022, 04:28:19 pm
Related to the console (command line) are terms such as standard input and standard output. The input is usually the keyboard. The output is the screen. In windowing systems, the output is the console (command line) window.

The keyboard has a data buffer that stores the characters that correspond to the keystrokes pressed by the user (input stream). The screen buffer (output stream) is bound to the screen. So the data at the console input is separated from the data at the console output.

The following procedures are used to retrieve data from the console input (keyboard): Read and ReadLn. The Write and WriteLn procedures are used to write data to the screen (console window). The "Ln" suffix stands for a line of text. The line of text consists of a string followed by a delimiter. They are different for different operating systems: CR (Mac), LF (Unix/Linux) or CRLF (Windows).

The Read procedure reads only as many characters as it can put in the variable. So you can pass several variables to it as arguments. The ReadLn procedure, on the other hand, reads the characters from the buffer together with the text delimiter. In both cases, characters are removed from console input after reading. Both of these routines can convert characters to base data types.

The Write procedure transfers the string that is displayed in the console window. The WriteLn procedure, on the other hand, adds a delimiter to the transferred characters. The result is that in the latter case, after writing text to the console window, the text cursor should move to the next line in the console window.

So if the WriteLn procedure writes a string of characters and puts a delimiter at the end, the result is that the text cursor in the console will move to the next line. And that's it. Attempting to read anything using the ReadLn routine will in no way result in reading this delimiter, because the console input is separate from the console output (ie the keyboard buffer from the screen buffer).

Please note that the above-mentioned procedures do not convert the contents of variables that are programmer-defined types.

Finally, one more thing: the question of using the ReadLn procedure call without any arguments in your code. If no arguments are given, this routine will only read the string delimiter from the console input, but only if the user presses the Enter key. It is usually used to stop the system from closing the console window so that the user has time to read the text on the screen. If the call was not in the program code, the program would exit immediately after processing the data and displaying the results, which means that the console window would also be closed.

The above description is deliberately simplified to explain only the most important issues related to the console (command line) operation.
Title: Re: Readln not being executed after Read() (Solved)
Post by: Brizeux on February 26, 2024, 12:20:47 pm
Dear Marcov .
There is also a "small" problem with multiple lectures of strings when you use the "beautiful" EDI of Free Pascal : Making lecture (read/readln) of many strings dos'nt read "right" under the EDI ( here the *.con file or output or internal variable,  but read "O.K." by executing directly the *.exe file .
The second (etc...) read/readln of a string doesn't work properly. Friendly. Yves.
TinyPortal © 2005-2018