是否可以增加控制台应用程序为readln
接受的字符数。
似乎只允许您键入254个字符
在Delphi中再现
档案>新>其他>控制台应用程序
将代码更改为以下
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.
将此字符串粘贴到正在运行的应用程序中(其为300个字符的字符串)
ABCDEFHIL1ABCDEFHIL2ABCDEFHIL3ABCDEFHIL4ABCDEFHIL5ABCDEFHIL6ABCDEFHIL7ABCDEFHIL8ABCDEFHIL9ABCDEFHI10ABCDEFHI11ABCDEFHI12ABCDEFHI13ABCDEFHI14ABCDEFHI15ABCDEFHI16ABCDEFHI17ABCDEFHI18ABCDEFHI19ABCDEFHI20ABCDEFHI21ABCDEFHI22ABCDEFHI23ABCDEFHI24ABCDEFHI25ABCDEFHI26ABCDEFHI27ABCDEFHI28ABCDEFHI29ABCDEFHI30
对我来说,它会将字符串切掉254个字符
ABCDEFHIL1ABCDEFHIL2ABCDEFHIL3ABCDEFHIL4ABCDEFHIL5ABCDEFHIL6ABCDEFHIL7ABCDEFHIL8ABCDEFHIL9ABCDEFHI10ABCDEFHI11ABCDEFHI12ABCDEFHI13ABCDEFHI14ABCDEFHI15ABCDEFHI16ABCDEFHI17ABCDEFHI18ABCDEFHI19ABCDEFHI20ABCDEFHI21ABCDEFHI22ABCDEFHI23ABCDEFHI24ABCDEFHI25ABCD
答案 0 :(得分:18)
AFAIK,你不能让RTL的Readln()
函数接受更多字符(虽然在内部,它被编码为运行一个应该能够处理超过254个字符的循环)。默认情况下,当您将300-char测试字符串粘贴到控制台窗口时,即使在按 Enter 之前,它也会停止在254处获取字符。
但是,您可以使用其他方法 - 拨打GetStdHandle(STD_INPUT_HANDLE)
,然后在ReadFile()
上调用HANDLE
,以便阅读您想要的内容。如果您使用至少300字节的缓冲区,它将很乐意接受您的300-char测试字符串:
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.
然后,您可以让RTL通过将HANDLE
包裹在THandleStream
和TStreamReader
中来处理缓冲(后者允许您指定缓冲区大小 - 默认为1024 bytes),例如:
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.
答案 1 :(得分:9)
RTL足够灵活,可以覆盖文件设备驱动程序默认值。它甚至允许您编写自己的驱动程序,但是根据您的需要,您需要做的就是提供足够的缓冲区来保存您的输入。
没有任何file
参数Readln
使用全局Input
以便您将要修改的内容:
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
var MyTest : String;
Buff: array[0..511] of Char;
begin
try
TTextRec(Input).BufSize := SizeOf(Buff);
TTextRec(Input).BufPtr := @Buff;
ReadLn(MyTest);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.