Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ Копирование строки файла

Автор: off 18.04.2008 22:49

Дан текстовый файл. В нем кроме обычных символов встречается команда \ins NN xx...xxx, где NN-двузначное число, xx...xxx - строка. Команда должна вставлять строку xx...xxx в данное место (нумерация строк с единицы). Запись результат во второй файл.
Не понимаю как копировать строку во второй файл
Вот,что написал я:


uses crt;
var f1,f2:text; i,n:integer; str:string;
begin clrscr;
Assign(f1,'1.txt'); Reset(f1);
Assign(f2,'2.txt'); Rewrite(f2);
n:=0;
While not EOF(f1) do begin
readln(f1,str); i:=0;
While (i<>Length(str)) do begin
inc(i);
if (str[i]='\') and (i+6<=Length(str)) then begin
if (copy(str,i+1,4)='ins ')and(str[i+5] in ['0'..'9'])and
(str[i+6] in ['0'..'9']) then begin
i:=i+6; inc(n); write(f2,n);
end;
end else write(f2,str[i]);
end;
writeln(f2);
end;
close(f1); close(f2);
readkey;
end.


Помогите))В общем нужно взять строку после \ins NN и копировать её во второй файл в NN-ную строку

Автор: off 20.04.2008 21:58

Спасите,пожалуйстааа.Послезавтра последний срок!!

Автор: klem4 21.04.2008 1:52

Ты бы поточнее задание привел и текст - пример входного файла...

Вот такое допустимо ?

Цитата

пертва\insястрока
во вотой нету второго параметра для ins \ins 42
а вот третья нормальная ? \ins 12 qwerty!
\ins 32 string!


просто надо ж знать насколько сложный парсер должен быть ...

Автор: off 21.04.2008 13:11

Не понял что то я...
В общем текстовый файл:

Код
sdkfhasdk \ins 11 sdjfndjscb ds
yyrt \ins 13 dfbfwsbweew sdkljcnds tr
de \ins 2 fgre

то,что после \ins 11,нужно копировать во второй файл в 11 строку;
то,что после \ns 13,копировать во второй файл в 13 строку и т.д.
то,что после \ns 2 вообще не нужно ,т.к. рассматриваются только двузначные числа...
не знаю как ещё объяснить))

Автор: klem4 21.04.2008 14:07

в общем так, формат команды такой:

<{пробел | начало строки}>\ins <пробел><двузначное число><пробел><текст до конца строки>

верно ?

Автор: off 21.04.2008 14:26

ну что то типа того.и вот этот <текст до конца строки> нужно копировать во второй файл(заранее пустой) в строку под номером <двузначное число>

Автор: klem4 24.04.2008 19:50

если еще актуально, вот держи:

{$B-}
function StrToByte(const s: string): byte;
var
value, err: integer;
begin
val(s, value, err);
StrToByte := value;
end;

type
PCommand = ^Command;
Command = object
pos: integer;
msg: string;
nextCmd: PCommand;
constructor Create(const position: integer; const message: string);
destructor Free;
end;

constructor Command.Create(const position: integer;
const message: string);
begin
pos := position;
msg := message;
nextCmd := nil;
end;

destructor Command.Free;
begin
nextCmd := nil;
end;

type
CommandList = object
first: PCommand;

constructor Create;
destructor Free;
procedure Add(const pos: integer; const message: string);
procedure Execute(const fileName: string);
end;

PCommandList = ^CommandList;

constructor CommandList.Create;
begin
first := nil;
end;

destructor CommandList.Free;
var
pCmd: PCommand;
begin
while first <> nil do begin
pCmd := first;
first := first^.nextCmd;
pCmd^.Free;
dispose(pCmd);
end;
end;

procedure CommandList.Add(const pos: integer; const message: string);
var
pCmd, pFirst, pred: PCommand;
begin
new(pCmd, Create(pos, message));

if first = nil then
first := pCmd
else begin

pFirst := first;
pred := nil;

while (pFirst <> nil) and (pos > pFirst^.pos) do begin
pred := pFirst;
pFirst := pFirst^.nextCmd;
end;

if pFirst = nil then
pred^.nextCmd := pCmd
else if pred = nil then begin
pCmd^.nextCmd := first;
first := pCmd
end else begin
pred^.nextCmd := pCmd;
pCmd^.nextCmd := pFirst;
end;
end;
end;

procedure CommandList.Execute(const fileName: string);
var
f: Text;
pFirst: PCommand;
filePos: integer;
begin
assign(f, fileName);
rewrite(f);

pFirst := first;

filePos := 0;
while pFirst <> nil do begin
while filePos <> pFirst^.pos - 1do begin
writeln(f, '');
inc(filePos);
end;
writeln(f, pFirst^.msg);
inc(filePos);
pFirst := pFirst^.nextCmd;
end;

close(f);
end;

type
Parser = object
constructor Create;
destructor Free;

function IsCommand(const s: string;
const p: byte;
var _pos: byte;
var msg: string): boolean;

procedure Parse(const cmdFileName, outFileName: string);
end;

constructor Parser.Create;
begin
end;

destructor Parser.Free;
begin
end;

function Parser.IsCommand(const s: string;
const p: byte;
var _pos: byte;
var msg: string): boolean;
begin
if (p + 8 <= length(s)) and
(s[ p + 4 ] = ' ') and
(s[ p + 5] in ['0'..'9']) and
(s[ p + 6] in ['0'..'9']) and
(s[ p + 7] = ' ') and
( ( p = 1) or (s[ p - 1 ] = ' '))
then begin

_pos := StrToByte(copy(s, p + 5, 2));
msg := copy(s, p + 8, 255);
IsCommand := true;

end else IsCommand := false;
end;

procedure Parser.Parse(const cmdFileName, outFileName: string);
var
cmdFile, outFile: Text;
cmdList: PCommandList;

s, msg: string;
p, _pos: byte;
cmdFind: boolean;
begin
assign(cmdFile, cmdFileName);

{$I-}
reset(cmdFile);
{$I+}

if IOResult <> 0 then begin
writeln('Can''t open file "', cmdFileName, '"');
readln;
halt(1);
end;

new(cmdList, Create);

while not eof ( cmdFile ) do begin
readln(cmdFile, s);

p := 1;
cmdFind := false;

repeat
p := pos('\ins', copy(s, p, 255));

if p > 0 then begin
cmdFind := IsCommand(s, p, _pos, msg);

if cmdFind then
cmdList^.Add(_pos, msg);

inc(p, 4);
end;
until (p = 0) or (cmdFind)
end;

cmdList^.Execute(outFileName);

dispose(cmdList, Free);

close(cmdFile);
end;

var
pr: ^Parser;

begin
new(pr, Create);
pr^.Parse('c:\commands.txt', 'c:\result.txt');
dispose(pr, Free);
end.


Цитата(COMMANDS.TXT)

\ins 123 pqweqweqweqweqwe
qweqweqwe\ins eqweq 03 213
\ins 01 THIS IS FIRST STRING
\ins 03 THIS IS THIRD STRING
qweo fhuiqhwof\ins 32
fqwe \ins 04 THIS IS FOURS STRING \ins 05 5555


Цитата(RESULT.TXT)
THIS IS FIRST STRING

THIS IS THIRD STRING
THIS IS FOURS STRING \ins 05 5555