memfile
Модератор: Модераторы
memfile
как создать файлы не на диске, а в памяти?
Cheb писал(а):TMemoryStream ?
а без классов никак?
просто задачка на парсинг, со стандартного ввода поступают данные, за один заход боюсь что их не смогу обработать, нада бы их в файл в памяти переписать и по нему уже алгоритм гонять ...
да еще когда со стандарнтного ввода данные поступают не могу конец файла поймать
while not eof do - не срабатывает - чем можно заменить?
со стандартного ввода поступают данные, за один заход боюсь что их не смогу обработать,
Тогда более разумного решения чем TMemoryStream и быть не может.
да еще когда со стандарнтного ввода данные поступают не могу конец файла поймать
А он там вообще бывает, этот конец?
И вообще - кто пишет данные, которые ты получаешь через стандартный ввод?
- shade
- энтузиаст
- Сообщения: 879
- Зарегистрирован: 21.02.2006 19:15:48
- Откуда: http://shamangrad.net/
- Контактная информация:
shade писал(а):Mayor писал(а):while not eof do - не срабатывает - чем можно заменить?
Попробуй заменить на while not seekeof do, только учти, что слово seek там не случайно... он пропускает все пробельные символы...
а вата, а никак стандартный ввод не приравнять к file of byte переменной?
я уже просто начал работать с filepos(f) > filesize(f)
что нарушает условия задачи - программа должна читать со стандартного канала ввода, а не из файла на диске
а никак стандартный ввод не приравнять к file of byte переменной?
Попробуй так:
Код: Выделить всё
Reset(f);
FileRec(f).Handle := StdInputHandle;
Но тип FileRec описан в filerec.inc, который не включен в интерфейс модуля system.
Поэтому его придется описать в своей проге или включить filerec.inc.
Но Eof все равно выдает ошибку.
Если прога не кроссплатформенная, то лучше попробуй использовать прямые системные вызовы.
Такая схема работает получше
но все равно не так, как нужно.
Если подать на вход файл с диска - все замечательно,
а если вывод другой проги - получается максимум 17 кбайт (под WinXP).
Код: Выделить всё
program project2;
{$APPTYPE CONSOLE}
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes
{ add your units here };
var
si, so: THandleStream;
sm: TMemoryStream;
begin
si := THandleStream.Create(StdInputHandle);
so := THandleStream.Create(StdOutputHandle);
sm := TMemoryStream.Create;
sm.LoadFromStream(si); // грузим в память
so.CopyFrom(sm, sm.Size); // выводим в stdout
sm.Free;
so.Free;
si.Free;
end.
но все равно не так, как нужно.
Если подать на вход файл с диска - все замечательно,
а если вывод другой проги - получается максимум 17 кбайт (под WinXP).
-
SAK
- постоялец
- Сообщения: 158
- Зарегистрирован: 17.02.2006 23:45:14
- Откуда: Тим
- Контактная информация:
Зачем всё усложнять? Создаём динамический массив из строк и сохраняем туда входные данные, потом его обрабатываем как угодно.
Если явно не указан файл, то процедура readln читает данные из файла Input, поэтому и проверять на конец файла надо его. Если данные вводятся с клавиатуры, то признаком конца файла является нажатие Ctrl+Z.
Кстати, если явно не указан файл, то write/writeln выводят в файл Output.
Код: Выделить всё
program Project1;
{$mode objfpc}{$H+}
var ss: array of string;
n: LongInt;
begin
SetLength (ss, 0);
n:=0;
while not eof(Input) do
begin
SetLength(ss, n+1);
Readln(ss[n]);
inc(n)
end;
for n:=0 to High(ss) do Writeln(ss[n]);
end.Если явно не указан файл, то процедура readln читает данные из файла Input, поэтому и проверять на конец файла надо его. Если данные вводятся с клавиатуры, то признаком конца файла является нажатие Ctrl+Z.
Кстати, если явно не указан файл, то write/writeln выводят в файл Output.
- shade
- энтузиаст
- Сообщения: 879
- Зарегистрирован: 21.02.2006 19:15:48
- Откуда: http://shamangrad.net/
- Контактная информация:
Если нужно прочесть точ-в-точ то что передали (без замены \r\n -> \n), то обрати внимание на SetTextLineEnding - иначе может просто удалить соответствующую строчку - под Windows вроде работает...
PS: только конструкция s := s + ch; скорее всего вызовет тормоза на больших файлах, потому нужно заюзать что-то типа SetLength(s); s[len] := ch; inc(len); Причем SetLength вызывать по реже, например SetLength(s, Length(s) + Length(s) div 4 + 1);
Позже дописал:
короче я бы попробовал так:
Код: Выделить всё
program test;
var
s: string;
ch: char;
begin
s := '';
SetTextLineEnding(input, #13);
while not eof do
begin
read(ch);
s := s + ch;
end;
writeln(s);
end.PS: только конструкция s := s + ch; скорее всего вызовет тормоза на больших файлах, потому нужно заюзать что-то типа SetLength(s); s[len] := ch; inc(len); Причем SetLength вызывать по реже, например SetLength(s, Length(s) + Length(s) div 4 + 1);
Позже дописал:
короче я бы попробовал так:
Код: Выделить всё
program test;
{$mode objfpc}
function ReadInput: AnsiString;
var
s: array of char;
capacity: longint;
RealLength: longint;
begin
RealLength := 0;
capacity := 1024;
SetLength(s, capacity);
SetTextLineEnding(input, #13);
while not eof do
begin
if RealLength = capacity then
begin
SetLength(s, capacity + capacity div 4 + 1);
end; // if
read(s[RealLength]);
Inc(RealLength);
end;
SetString(Result, @s[0], RealLength);
end;
var
text: AnsiString;
begin
text := ReadInput;
writeln('Input size in bytes: ', Length(text));
writeln('content:');
write(text);
writeln('----------------- end ---------------');
end.
да еще когда со стандарнтного ввода данные поступают не могу конец файла поймать
стандарт posix позволяет даже под виндой :
prog < file.bin
перенаправить на стандартный канал ввода файл или стандартный вывод другой программы
А он там вообще бывает, этот конец?
И вообще - кто пишет данные, которые ты получаешь через стандартный ввод?
естественно бывает ^D его посылает даже с клавиатуры, или ситема когда пайпе прога закрывается или файл заканчивается ..
а да респект всем особенно за анси стринг оказалось то что нада
- shade
- энтузиаст
- Сообщения: 879
- Зарегистрирован: 21.02.2006 19:15:48
- Откуда: http://shamangrad.net/
- Контактная информация:
