Здравствуйте, Андрей fult.
Здравствуйте, Андрей fult.
Код в приложении. Есть комментарии - не поймете что - пишите тут. Поясню
Исходные файлы перед объединением сортируются по возрастанию
Если все нормально, программа ничего на экран не выводит - если нужно, легко исправить. (Справитесь?)
Содержимое in1.txtСодержимое in2.txt Содержимое выходного файла out.txtОбратите внимание, что исходные файлы изменяются - становятся отсортированными
С недопустимыми числами не экспериментировал. Могут быть сбои, хотя поначалу и это предусматривал
Приложение:
{Вариант, в котором нет ограничений на размер файлов.
ВРАНЬЁ, конечно. Строки пересчитываются и используется тип Integer, так что,
сейчас в файле исходном каждом может быть не более 32565 чисел
Но, ессно, заменив типы переменных можно существенно увеличить, а можно и не считать числа
- просто длиннее станет код}
CONST
FileName1: String = 'in1.txt';
FileName2: String = 'in2.txt';
FileOut : String = 'out.txt';
procedure SortTextFile(aFileName: String);
{Файлы должны быть закрыты}
CONST
TempFileName = 'temp.txt';
BackFileName = 'back.txt';
var
f_src, f_back, f_temp: Text;
i, i_min, number_no, number_no_min, number_count: Integer;
{используется для упорядочения текстовых файлов}
begin
{Алгоритм такой: прочитываем файл - запоминаем значение наименьшего,
записываем во временный файл
опять читаем сначала исходный и записываем в резервный,
если в первый раз встречаем значение, равного наименьшему, то
в резервный не записываем
Затем переименовываем резервный в исходный и опять, пока}
assign(f_src, aFileName);
{$I-} Reset(f_src); {$I+}
if IOResult <> 0 then Exit;
Assign(f_temp, TempFileName);
Rewrite(f_temp); {отсортированный файл}
{Подсчитаем число чисел в файле}
number_count:=0;
while NOT SeekEOF(f_src) do
begin
Read(f_src, i);
inc(number_count);
end;
while number_count > 0 do begin
Reset(f_src);
{Ищем номер минимального числа}
Read(f_src, i_min);
number_no := 1;
number_no_min := 1;
While NOT SeekEOF(f_src) do begin
Read(f_src, i);
inc(number_no);
if i < i_min then begin
number_no_min := number_no;
i_min := i
end
end;
WriteLn(f_temp, i_min);
{Теперь нужно исключить это число из исходного
Переписываем в резервный, а затем переименовываем в исходный}
Assign(f_back, BackFileName);
Rewrite(f_back); number_no := 0;
Reset(f_src);
While NOT SeekEOF(f_src) do begin
Read(f_src, i); inc(number_no);
if number_no <> number_no_min then
WriteLn(f_back, i)
end;
dec(number_count);
Flush(f_back);
Close(f_back);
Close(f_src);
Erase(f_src);
Rename(f_back, aFileName);
end;
Flush(f_temp);
Close(f_temp);
{Теперь удалить старый и переименовать временный в исходный}
Erase(f_src);
Rename(f_temp, aFileName);
end;
TYPE
TtoRead = (file1, file2);
VAR
f1, f2, fout: Text;
i1, i2: Integer;
isf1, isF2: Boolean; {Флаги, что имеются считанные данные}
toRead: TtoRead; {Что считывать: файл1 или файл2}
BEGIN
Assign(f1, FileName1);
{$I-} Reset(f1);{$I+}
if IOResult <> 0 then begin
WriteLn('Не могу открыть файл ', FileName1);
WriteLn('Работа программы завершена. Нажмите любую клавишу');
ReadKey; Halt(1)
end;
Assign(f2, FileName2);
{$I-} Reset(f2);{$I+}
if IOResult <> 0 then begin
WriteLn('Не могу открыть файл ', FileName2);
WriteLn('Работа программы завершена. Нажмите любую клавишу');
ReadKey; Halt(1)
end;
Assign(fout, FileOut);
{$I-} Rewrite(fout);{$I+}
if IOResult <> 0 then begin
WriteLn('Не могу создать файл ', FileOut);
WriteLn('Работа программы завершена. Нажмите любую клавишу');
ReadKey; Halt(1)
end;
{завершается цикл как только закончатся ОБА файла
Если встретится ошибка чтения, то просто ЭТОТ файл перестает
считываться
Начальное считывание}
{$R+}
{включаем проверку на принадлежность диапазону. По умолчанию выключена}
{Упорядочение исходных файлов}
Close(f1); Close(f2);
SortTextFile(FileName1);
SortTextFile(FileName2);
Reset(f1); Reset(f2);
{Объединение упорядоченных}
isF1 := NOT SeekEOF(F1);
isF2 := NOT SeekEOF(F2);
if NOT(isF1) and NOT(isF2) then
begin {ни один не считан. Допустим в обоих ошибки чтения}
WriteLn('Не удается считывать информацию ни из одного файла');
WriteLn('Работа программы завершается. Нажмите любую клавишу');
ReadKey;
Close(f1); Close(f2); Close(fout);
Halt(2)
end;
if isF1 then begin
{$I-} Read(f1, i1); {$I+}
isF1 := IOResult = 0;
end;
if isF2 then begin
{$I-} Read(f2, i2); {$I+}
isF2 := IOResult = 0;
end;
repeat
while isF1 do begin
if NOT isF2 then
WriteLn(fout, i1)
else
begin
if (i1 <= i2) then
WriteLn(fout, i1)
else
Break;
end;
if SeekEOF(F1) then
isF1 :=FALSE
else begin
{$I-} Read(f1, i1); {$I+}
isF1 := IOResult = 0;
end
end;
while isF2 do begin
if NOT isF1 then
WriteLn(fout, i2)
else
begin
if (i2 <= i1) then
WriteLn(fout, i2)
else Break;
end;
if SeekEOF(F2) then
isF2 := False
else
begin
{$I-} Read(f2, i2); {$I+}
isF2 := IOResult = 0;
end
end;
until (NOT isF1) and (NOT isF2); {условия выхода}
Close(f1);
Close(f2);
Flush(fout); {Вывод в текстовый файл медленный - нужно дождаться}
Close(fout);
END.