Freeman пишет:Процедура ReadLn здесь одна. Если вспомнить, как работает стандартный ввод в Паскале, это видится логичным:
Получается, что реальный ввод происходит после ReadLn.
Например, такой код
program test;
{$APPTYPE CONSOLE}
var
A, B, C: Integer;
begin
Read(A, B); // числа через пробел
Write(A, ' ', B);
ReadLn(C); // число на той же строке через пробел, затем перевод строки
Write(' ', C);
ReadLn;
end.
Полный ввод произойдёт после ввода конца строки

Freeman пишет:Похоже, ввод придется делать через GetCh консоли.
Когда я делал модуль InOut для XDS Modula-2/Oberon-2 compiler, то там я реализовал всё через GetS, даже если вводится только Char.
▼Вот модуль InOut
EXTERN LoadLibrary ; in DLL.asm
EXTERN GetProcAddress ; in DLL.asm
EXTERN X2C_HALT ; in X2C.asm
GLOBAL InOut_BEGIN
GLOBAL InOut_Write
GLOBAL InOut_WriteLn
GLOBAL InOut_WriteInt
GLOBAL InOut_WriteCard
GLOBAL InOut_WriteString
GLOBAL InOut_Read
GLOBAL InOut_ReadCard
GLOBAL InOut_ReadString
READ_BUFFER_SIZE equ 80
SECTION .text
; ---------------------------------------------------------------------------- ;
InOut_BEGIN:
push ebx
push esi
push edi
push dword sz_console
call LoadLibrary
mov ecx, eax
mov ebx, GetProcAddress
push ecx
push dword sz_con_init
call ebx
mov [con_init], eax
push ecx
push dword sz_con_printf
call ebx
mov [con_printf], eax
push ecx
push dword sz_con_gets
call ebx
mov [con_gets], eax
push dword [32]
push -1
push -1
push -1
push -1
call [con_init]
pop edi
pop esi
pop ebx
ret
; ---------------------------------------------------------------------------- ;
; PROCEDURE WriteString(v: ARRAY OF CHAR);
InOut_WriteString:
push ebx
push esi
push edi
push dword 0
push dword [esp + 4 + 4*4]
call [con_printf]
add esp, 8
pop edi
pop esi
pop ebx
ret 8
; ---------------------------------------------------------------------------- ;
; PROCEDURE WriteInt(v: INTEGER; w: CARDINAL);
InOut_WriteInt:
push ebx
push esi
push edi
push dword [esp + 4 + 3*4]
push dword [esp + 8 + 4*4]
push dword sz_format_int
call [con_printf]
add esp, 12
pop edi
pop esi
pop ebx
ret 8
; ---------------------------------------------------------------------------- ;
; PROCEDURE WriteLn;
InOut_WriteLn:
push dword 0
push dword sz_end_of_line
call InOut_WriteString
ret
; ---------------------------------------------------------------------------- ;
; PROCEDURE Write(v: CHAR);
InOut_Write:
push ebx
push esi
push edi
push dword [esp + 4 + 3*4]
push dword sz_format_char
call [con_printf]
add esp, 8
pop edi
pop esi
pop ebx
ret 4
; ---------------------------------------------------------------------------- ;
; PROCEDURE WriteCard(v: CARDINAL; w: CARDINAL);
InOut_WriteCard:
push ebx
push esi
push edi
push dword [esp + 4 + 3*4]
push dword [esp + 8 + 4*4]
push dword sz_format_card
call [con_printf]
add esp, 12
pop edi
pop esi
pop ebx
ret 8
; ---------------------------------------------------------------------------- ;
; PROCEDURE Read(VAR v: CHAR);
InOut_Read:
push ebx
push esi
push edi
mov esi, [PtrInReadBuffer]
lodsb
test al, al
jnz .read_buffer_not_empty
mov [PtrInReadBuffer], dword ReadBuffer
push dword READ_BUFFER_SIZE
push dword ReadBuffer
call [con_gets]
test eax, eax
jz X2C_HALT
mov esi, ReadBuffer
lodsb
.read_buffer_not_empty:
mov edi, [esp + 4 + 3*4]
stosb
inc dword [PtrInReadBuffer]
pop edi
pop esi
pop ebx
ret 4
; ---------------------------------------------------------------------------- ;
; PROCEDURE ReadCard(VAR v: CARDINAL);
InOut_ReadCard:
push ebx
push esi
push edi
mov ebx, [esp + 4 + 3*4]
push ebp
mov ebp, esp
sub esp, 16
lea edi, [esp]
mov ecx, 16
xor al, al
rep stosb
push dword 16
lea esi, [esp - 1*4]
push esi
call InOut_ReadString
xor ecx, ecx
xor eax, eax
.next:
lodsb
sub al, 48
cmp al, 9
jnbe .done
lea ecx, [ecx + ecx * 4]
lea ecx, [eax + ecx * 2]
jmp .next
.done:
mov [ebx], ecx
mov esp, ebp
pop ebp
pop edi
pop esi
pop ebx
ret 4
; ---------------------------------------------------------------------------- ;
; PROCEDURE ReadString(VAR v: ARRAY OF CHAR);
InOut_ReadString:
push ebx
push esi
push edi
mov esi, [PtrInReadBuffer]
lodsb
test al, al
jnz .read_buffer_not_empty
mov [PtrInReadBuffer], dword ReadBuffer
push dword READ_BUFFER_SIZE
push dword ReadBuffer
call [con_gets]
test eax, eax
jz X2C_HALT
mov esi, ReadBuffer
lodsb
.read_buffer_not_empty:
mov edi, [esp + 4 + 3*4]
mov ecx, [esp + 8 + 3*4]
.skip:
inc dword [PtrInReadBuffer]
jcxz .done
test al, al
jz .done
cmp al, " "
jnbe .next
dec ecx
lodsb
jmp .skip
.next:
jcxz .done
stosb
cmp al, " "
jbe .done
dec ecx
lodsb
inc dword [PtrInReadBuffer]
jmp .next
.done:
mov [edi], byte 0
pop edi
pop esi
pop ebx
ret 8
SECTION .data
; ---------------------------------------------------------------------------- ;
sz_end_of_line db 10,0
sz_format_int db "%*ld",0
sz_format_char db "%c",0
sz_format_card db "%*u",0
; ---------------------------------------------------------------------------- ;
sz_con_init db "con_init",0
sz_con_printf db "con_printf",0
sz_con_gets db "con_gets",0
sz_console db "/sys/lib/console.obj",0
; ---------------------------------------------------------------------------- ;
con_init dd 0
con_printf dd 0
con_gets dd 0
; ---------------------------------------------------------------------------- ;
PtrInReadBuffer dd ReadBuffer
ReadBuffer: resb READ_BUFFER_SIZE
В этом модуле существует внутренний буфер ReadBuffer размером READ_BUFFER_SIZE.
В этот буфер происходит чтение с помощью функции GetS, а затем уже мы обрабатываем(например, конвертируем строку в число) то, что было введено в этот буфер.
Аналогичным образом предлагаю сделать и здесь.
Freeman пишет:While console I/O procedures still non-standard
Как минимум функцию Write уже можно перенести в System и сделать стандартной.
По поводу WriteExt\ReadExt — в библиотеке Console в KolibriOS не поддерживается ввод\вывод чисел с плавающей точкой посредством встроенных функций, нужно самим делать дополнительно код конвертации(хотя лучше бы он был в системной библиотеке).
ReadLString — для длинных строк ещё нужен менеджер памяти.
Post's attachments
1.PNG 1.73 Кб, 73 скачиваний с 2020-06-24