Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi Console Application increase input character limit

Is it possible to increase the number of characters that the console app accepts for readln.

It seems to only allow you to type 254 characters

To Reproduce in Delphi

File > New > Other > Console Application

change the code to be as per below

program Project3;

{$APPTYPE CONSOLE} 

{$R *.res}

uses
  System.SysUtils;

var MyTest : String;
begin
  try
    readln(MyTest);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Paste this string in the running app ( its a 300 character string )

ABCDEFHIL1ABCDEFHIL2ABCDEFHIL3ABCDEFHIL4ABCDEFHIL5ABCDEFHIL6ABCDEFHIL7ABCDEFHIL8ABCDEFHIL9ABCDEFHI10ABCDEFHI11ABCDEFHI12ABCDEFHI13ABCDEFHI14ABCDEFHI15ABCDEFHI16ABCDEFHI17ABCDEFHI18ABCDEFHI19ABCDEFHI20ABCDEFHI21ABCDEFHI22ABCDEFHI23ABCDEFHI24ABCDEFHI25ABCDEFHI26ABCDEFHI27ABCDEFHI28ABCDEFHI29ABCDEFHI30

For me, it chops the string off at 254 characters

ABCDEFHIL1ABCDEFHIL2ABCDEFHIL3ABCDEFHIL4ABCDEFHIL5ABCDEFHIL6ABCDEFHIL7ABCDEFHIL8ABCDEFHIL9ABCDEFHI10ABCDEFHI11ABCDEFHI12ABCDEFHI13ABCDEFHI14ABCDEFHI15ABCDEFHI16ABCDEFHI17ABCDEFHI18ABCDEFHI19ABCDEFHI20ABCDEFHI21ABCDEFHI22ABCDEFHI23ABCDEFHI24ABCDEFHI25ABCD

enter image description here

like image 680
Dangas56 Avatar asked Feb 13 '18 23:02

Dangas56


1 Answers

AFAIK, you can't make the RTL's Readln() function accept more characters (though internally, it is coded to run a loop that should be able to handle more than 254 characters). It seems by default, when you paste your 300-char test string into the console window, it stops taking characters at 254 even before you press Enter.

But, you can use a different approach - call GetStdHandle(STD_INPUT_HANDLE) and then call ReadFile() on that HANDLE to read however much you want. If you use a buffer that is at least 300 bytes, it will happily accept your 300-char test string:

program Project3;

{$APPTYPE CONSOLE} 

{$R *.res}

uses
  System.SysUtils, Winapi.Windows;

var
  buf : array[0..299] of AnsiChar;
  MyTest: AnsiString;//string;
  hStdIn: THandle;
  dwNumRead: DWORD;
begin
  try
    //Readln(MyTest);
    hStdIn := GetStdHandle(STD_INPUT_HANDLE);
    ReadFile(hStdIn, buf, sizeof(buf), dwNumRead, nil);
    SetString(MyTest, buf, dwNumRead);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

You can then let the RTL handle that buffering for you, by wrapping the HANDLE in a THandleStream and TStreamReader (the latter lets you specify a buffer size - it defaults to 1024 bytes), eg:

program Project3;

{$APPTYPE CONSOLE} 

{$R *.res}

uses
  System.SysUtils, Winapi.Windows, System.Classes;

var
  MyTest : String;
  strm: THandleStream;
  reader: TStreamReader;
begin
  try
    //Readln(MyTest);
    strm := THandleStream.Create(GetStdHandle(STD_INPUT_HANDLE));
    try
      reader := TStreamReader.Create(strm);
      try
        MyTest := reader.ReadLine;
      finally
        reader.Free;
      end;
    finally
      strm.Free;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
like image 190
Remy Lebeau Avatar answered Sep 19 '22 14:09

Remy Lebeau