Помощь - Поиск - Пользователи - Календарь
Полная версия: Текстовые файлы
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Clerick
Дали новую тему, текстовые файлы. Давали студенты и никто из группы ничего не понял... blink.gif
А задачи нужно сдать завтра. wacko.gif Помогите хоть с какими-нибудь двумя!!!

1. Дан текстовый файл, содержащий целые числа. Найти
• Арифметическое среднее чисел в файле;
• Номер максимального элемента в файле; (решена)

2. Дан текстовый файл, содержащий строки. Найти самые короткие строки. (решена)

3. Даны два текстовых файла. Записать в третий только те строки, которые есть и в первом и во втором файлах.

4. Даны два файла А и В(тип элементов одинаковый). Поменять местами содержимое этих файлов.
Использовать процедуру Rename не разрешается.

Заранее спасибо!!! smile.gif
klem4
FAQ : Файлы + поиск по форуму, все решалось неоднократно.

Ждешь готового решения ? Делай сам, будут ошибки мы исправим.
Clerick
Цитата(klem4 @ 23.03.2006 20:52) *

FAQ : Файлы + поиск по форуму, все решалось неоднократно.



Спасибо!!! smile.gif

Цитата
Ждешь готового решения ? Делай сам, будут ошибки мы исправим.


Проблема в том, что с данной темой ни разу не сталкивался и в принципе не знаю что делать... blink.gif

Но есть ссылка!!! Почитаем, подумаем, поделаем...



Почитали, подумали и ни к чему не пришли...
Можно хотя бы одну решить, в качестве примера?(понимаю, что наглею, но желательно бы что-нибудь из первых двух)
Ozzя
Цитата
Можно хотя бы одну решить, в качестве примера?

Если только в качестве примера rolleyes.gif
Цитата
1. Дан тестовый файл, содержащий целые числа. Найти
• Арифметическое среднее чисел в файле;

Код
const
  n = 255;
var
  f : file of integer;
  i : integer;
  x : integer;
  sum:real;
begin
  Randomize;
  { Заполнение файла }
  Assign(F, 'integer.dat');
  Rewrite(F);
  for i:=1 to n do
    begin
      x := Random (MaxInt);
      write(f,x);
    end;
  Close(F);
  { Обработка файла }
  Reset(F);
  sum:=0;
  i:=0;
  while not eof(f) do
    begin
      read(f,x);
      sum:=sum+x;
      i:=i+1;
    end;
  sum:=sum/i;
  Close(F);
  WriteLn('Number of elements = ',i);
  WriteLn('Sum of elements = ',sum);
end.
klem4
Держи первое, дабьше делай сам.

uses crt;

var

f : text;

count, nmax, n : integer;

sr : single;

begin

clrscr;

assign(f, 'c:\first.txt'); // связываемся с файлом

reset(f); // открываем файл для чтение (он должен быть уже создан)

sr := 0;
count := 0;
nmax := 0;

while not(eof(f)) do begin // пока не достигнут конец файла
readln(f, n); // читаем число
inc(count); // увеличиваем счетчик
sr := sr + n; // увеличиваем сумму
end;

close(f); // завершаем раюоту с файлом

if count <> 0 then begin // считаем среднее арифметическое
sr := sr / count;
writeln('Sr = ', sr : 3 : 3);
writeln('Count = ', count);
end else writeln('Oops, count = 0'); // файл был пуст

end.




firts.txt :

1
2
7
0
5

Sr = 3.0
count = 5;
Ozzя
Цитата
1. Дан тестовый файл,

Опечатка? текстовый?

Хм .. а я даже и не заметил smile.gif Видимо да ...
Clerick
Спасибо!!! И извиняюсь за ошибку!!!

Наткнулся на другую задачу и застрял... Дана матрица m на n заполненная random от а до b. Нужно записать ее в файл. Составил прогу:
ses crt;
const n=5;
m=5;
var f:text;
j, i, a, b:integer;
g:array [1..n,1..m] of integer;
begin
Read(a,b);
randomize;
for i:=1 to n do begin
for j:=1 to m do begin
g[i,j]:=random (b-a)+a;
Write (g[i,j]:3);
end;
Writeln;
end;
assign (f, 'text.txt');
for i:=1 to n do begin
for j:=1 to m do begin rewrite (f);
Writeln (f, g[i,j]);
end;
end;
Readln;
end.

А она в файл не записывает... В чем ошибка?
Clerick
Цитата(klem4 @ 24.03.2006 11:14) *


firts.txt :

1
2
7
0
5

Sr = 3.0
count = 5;




А если я в одной строке два числа или больше ставлю? blink.gif
Ozzя
Цитата
for j:=1 to m do begin
rewrite (f);


Ты внутри цикла каждый раз уничтожаешь файл и создаешь его заново.
Вынеси за цикл:
rewrite (f);
for i:=1 to n do
for j:=1 to m do
Writeln (f, g[i,j]);


Цитата
А если я в одной строке два числа или больше ставлю?

Тогда усложнится процедура чтения и обработки файла. Зачем нужны лишние хлопоты?
Clerick
Цитата(Ozzя @ 24.03.2006 17:31) *

Вынеси за цикл:

Вынес и все равно файл пустой остается...
Цитата

[Тогда усложнится процедура чтения и обработки файла. Зачем нужны лишние хлопоты?

Так интересно же как это будет выглядеть!!! А с другой стороны, допустим, файл такой дали. Тогда что делать?
Ozzя
const
n=5;
m=5;
var
f:text;
j, i, a, b:integer;
g:array [1..n,1..m] of integer;
begin
Read(a,b);
randomize;
for i:=1 to n do
for j:=1 to m do
g[i,j]:=random (b-a)+a;
assign (f, 'c:\bp\text.txt');
rewrite (f);
for i:=1 to n do
for j:=1 to m do
Writeln (f, g[i,j]);
close(f);
readln;
end.
Clerick
О теперь работает! smile.gif

Close (f); забыл поставить... blink.gif

Цитата(Ozzя @ 24.03.2006 17:31) *

[Тогда усложнится процедура чтения и обработки файла. Зачем нужны лишние хлопоты?

Цитата

Так интересно же как это будет выглядеть!!! А с другой стороны, допустим, файл такой дали. Тогда что делать?


Только вопрос на ту же тему как записать в файл именно "матрицу"?

Например:
5 3 6 7 5
4 4 7 8 1
7 2 9 7 4
4 7 8 4 5
Ozzя
uses
crt;
const
n=5;
m=5;
var
f:text;
j, i, a, b:integer;
g:array [1..n,1..m] of integer;
begin
Read(a,b);
randomize;
for i:=1 to n do
for j:=1 to m do
g[i,j]:=random (b-a)+a;
assign (f, 'c:\bp\text.txt');
rewrite (f);
for i:=1 to n do
begin
for j:=1 to m do
Write (f, g[i,j],' ');
writeln(f);
end;
close(f);
readln;
end.
Clerick
Теперь все одну строчку... blink.gif
Ozzя
Все нормально отрабатывает blink.gif
Clerick
Все в норме!!! Пропустил один оператор... blink.gif

blink.gif Возник еще вопрос! Как имея файл со некоторым количеством строк, определить сколько их?
Altair
Цитата
Как имея файл со некоторым количеством строк, определить сколько их?

while not eof(f) do begin readln(f,s); inc(result) end;

результат (количество строк) после выполнения кода в переменной result (int).
Clerick
Если я прав(приближенно), то след. прога должна выводить содержимое файла
uses crt;
var f:text;
j, i, max, c:integer;
s:string;
begin
assign (f, 'text.txt');
reset (f);
while not eof(f) do
begin
Readln(f,i);
inc(j);
end;
for i:=1 to j do begin
while not eoln(f) do
begin
readln (f,s);
write (s:2);
Writeln;
end; end;
close(f);
end.

А она не выводит. В чем ошибка?
Ozzя
uses
crt;
var
f:text;
j, i, max, c:integer;
s:string;
begin
assign (f, 'text.txt');
reset (f);
while not eof(f) do
begin
Readln(f,s);
Writeln(s);
inc(j);
end;
close(f);
end.
Clerick
Спасибо!!!

Появился вопр. к з.2 можно её решить след. образ. Сосчитать кол-во символов в каждой строке, загнать в массив, а потом сравнить и выявить min? Или можно проще?
Ozzя
Можно проще. Сразу при считывании строк из файла находи минимальные из них.
Clerick
Считывание строк в цикле?
Ozzя
Ну да

while not eof(f) do
begin
readln(f,s);
n:=length(s);
if n< min then
min:=n;
....
end;
мисс_граффити
"найти самые короткие строки" - это вывести их номера или их сами?
Clerick
Цитата(мисс_граффити @ 25.03.2006 20:59)
вывести их номера или их сами

Номера! smile.gif

to Оззя
uses
crt;
var
f:text;
j, i, n, c, min:integer;
s:string;
begin
assign (f, 'text.txt');
reset (f);
Readln (f,s);
min:=length(s);
while not eof(f) do
begin
readln(f,s);
n:=length(s);
if n<min then
min:=n;
end;
close(f);
Writeln (min);
readln;
end.


Выводит 4. text.txt:

6 5 4 5 6 4 4 5 6
2 3 6 7 7 8
3 4 4 1 3
4 4 2 3 3 3 3 3
3 1

Где опять лопухнулся?
мисс_граффити
если номера - тогда лучше правда массив...

она тебе выводит длину минимальной строки...
а чему она должна быть равна?
у меня с тем же текстом выводит 3: то есть правильно (последняя строка: 3 пробел 1).
может, у тебя там еще какой-то символ?
Clerick
Цитата(мисс_граффити @ 25.03.2006 21:23) *

у меня с тем же текстом выводит 3: то есть правильно (последняя строка: 3 пробел 1).
может, у тебя там еще какой-то символ?

Да нет вроде ничего нет. Хотя сейчас посмотрю.

Все теперь все в норме!

А как вывести номер строки?
мисс_граффити
для этого его надо отслеживать.
например, делай так, как изначально собирался - через массив и выводи номера минимальных элементов.
только здесь возникнет вопрос по поводу размера массива...
hardcase
Нужно просто считать итерации и запоминать итерацию, на которой обнаружена самая короткая сторока.

кроме того у вас ошибка вот здесь:
   assign (f, 'text.txt');
reset (f);
Readln (f,s); //уберите эту строку! вдруг файл пустой? - будет ошибка
min:=length(s); // замените на min:=MaxInt; или на min:=$7FFFFFFF;

мисс_граффити
Цитата(hardcase @ 25.03.2006 21:10) *

Нужно просто считать итерации и запоминать итерацию, на которой обнаружена самая короткая сторока.
кроме того у вас ошибка вот здесь...

у нас по условию таких строк несколько.
сколько именно - заранее не знаем.

по-хорошему, надо проверять, есть ли вообще этот файлик ;)
hardcase
Цитата(мисс_граффити @ 25.03.2006 22:48) *

у нас по условию таких строк несколько.
сколько именно - заранее не знаем.

Так в чём проблема? Формируем список, каждый элемент которого будет содержать индекс строки.
Вот и алгоритм: Если нашли строку короче, чем были до этого, то гробим предидущий список, и создаём новый (из 1 элемента) который заносим текущй индекс, если строка по длине такая же, то добавляем в текущий список.

В конце просто выбрасываем этот список на печать.
program FindAllMinStrings;

type
PElement = ^TElement;
TElement = record
index: integer; //здесь будет храниться номер строки
str: string; // сама строка
next: PElement; //следующий элемент в списке
end;

const InputFileName = 'test.txt';

var lst: PElement = nil;

// процедура будет разрушать список - возвращаем память
procedure KillList;
// обычный рекурсивный проход по элементам списка
// можно, конечно, и в цикле, но я привык к SML
procedure Kill(El: PElement);
begin
if El = nil then Exit;
Kill(El^.next);
Dispose(El)
end;
begin
Kill(lst);
lst:=nil;
end;

// выделяет память под новый элемент списка и возвращает указатель
// на него
function NewElement(AIndex: integer; const AStr: string): PElement;
var El: PElement;
begin
New(El);
El^.index:=AIndex;
El^.str:=AStr;
El^.next:=nil;
NewElement:=El;
end;

// цепляет к новому элементу список lst
// cons - это в LISP :-) была такая операция
procedure Cons(El: PElement);
begin
El^.next:=Lst;
Lst:=El;
end;

// выводит на печать список - тоже рекурсивно
// люблю я рекурсию :-)
procedure PrintList;
procedure Print(El: PElement);
begin
if El = nil then Exit;

// так как список наш сформирован с номерами строк (index)
// задом на перёд, то сначала нада напечатать то, что было ранешнее
Print(El^.next);
// а потом текущий элемент
WriteLn(El^.index, ': ', El^.str)
end;
begin
Print(lst);
end;

var InputFile: textfile; // файло со строками
minlen: integer = MaxInt; // текущая минимальная длина строки её инициализируем максимальным целым
curstr: string; // текущая строка
curlen: integer; // длина текущей строки
i: integer = 0; // индексатор строк - нумерация с 0 начинается
begin
Assign(InputFile, InputFileName);
Reset(InputFile);
while not EOF(InputFile) do begin
ReadLn(InputFile, curstr);
curlen:=Length(curstr);
if curlen < minlen then begin
// нашли строку короче, чем уже имеем - гробим список
KillList;
// и строим его заново
Cons(NewElement(i, curstr))
end else if curlen = minlen then begin
// нашли строку по длине совпадающую с текущим минимумом
// благополучно запоминаем её и индекс
Cons(NewElement(i, curstr))
end;
inc(i); // не забываем считать строки :-)
end;
Close(InputFile);
// печатаем что есть
PrintList;
// и чистим память (хотя можно и без этого)
KillList;
end.

Вот собсна. Делфю грузить неохота, но должно работать.
мисс_граффити
Цитата(hardcase @ 26.03.2006 0:16) *

Вот собсна. Делфю грузить неохота, но должно работать.

Возможно... хотя у меня делфи на Assign ругается - предпочитает AssignFile.
Но проблема в том, что списки в школе и в неспециализированных вузах не дают обычно. Сомневаюсь, что Clerick с ними сталкивался... соответственно, так решенная задача может вызвать подозрения препода.
Clerick
Цитата(мисс_граффити @ 26.03.2006 11:07) *

Но проблема в том, что списки в школе и в неспециализированных вузах не дают обычно. Сомневаюсь, что Clerick с ними сталкивался... соответственно, так решенная задача может вызвать подозрения препода.


Это предыдущая тема, которую мы прошли(физмат профиль в школе)! Но решали лишь элементарные задачи. Поэтому большая просьба к Hardcase: поясни свой код!!! !mol1.gif !mol1.gif !mol1.gif

Зы: мой компилятор BP7
hardcase
Коментарии добавил. (вроде там и комментировать-то нечего - чай не Win32 API)

BP7 не имею - я его ВООБЩЕ никогда не имел и в глаза только в школе видел пару раз. Вот такие мы сирые и необразованные. FPC - нету, да и собсна, он мне не нужен. TMT лежал где-то, но и он, скорее, как экспонат лежит.

Думаю, скомпилироваться должно, я только не знаю, BP7 поддерживает динамические строки, или нет?

Цитата(мисс_граффити @ 26.03.2006 9:07) *

Возможно... хотя у меня делфи на Assign ругается - предпочитает AssignFile.

есть у класса TPersistent метод Assign - вот и ругается делфи на него. Можно писать System.Assign(FileVariable, FileName);


BP и TP это не откомпилируют 100 %, hardacase, тебе на кажется что раздел 32 битные компиляторы находится в другом месте ?
Clerick
Цитата(klem4 @ 26.03.2006 13:27) *

BP и TP это не откомпилируют 100 %, hardacase, тебе на кажется что раздел 32 битные компиляторы находится в другом месте ?


Не откомпилируют что?
hardcase
Не знаю- не знаю, всё должно скомпилиться - вот посмотрел предыдущий вариант решения задачи - Clerick это скомпилит.

Только при чём тут вообще разрядность?
На дворе 2006 год! Тут уже переходят на 64 разрядные машины.
Мне казалось, что 16-бит компилеры благополучно вышли из употребления (померли) ещё 10 лет назад... Зачем вообще акцентироватся на этом?
Clerick
Начались проблемы...

var lst: PElement ; = nil; Требует поставить ; в указанном месте...

После того как ставлю, требует begin, а дальше говорит error in statement....
hardcase
А проинициализировать переменные в begin .. end - не светит?
Clerick
Что значит проинициализировать и как это сделать?
hardcase
Я не знаю, что такое BP7, он похоже не поддерживает инициализацию переменных при объявлении
Код

var lst: PElement = nil;

поэтому стоит заменить на
Код

var lst: PElement;
...
begin
  lst:=nil;
  ....
  Assign(...)
  ...  
end.

с другими переменными - аналогично
Clerick
Цитата(hardcase @ 27.03.2006 0:00) *

Я не знаю, что такое BP7

Если мне не изменяет память то это Borland Pascal 7.
klem4
Цитата(hardcase @ 26.03.2006 19:23) *

Не знаю- не знаю, всё должно скомпилиться - вот посмотрел предыдущий вариант решения задачи - Clerick это скомпилит.

Только при чём тут вообще разрядность?
На дворе 2006 год! Тут уже переходят на 64 разрядные машины.
Мне казалось, что 16-бит компилеры благополучно вышли из употребления (померли) ещё 10 лет назад... Зачем вообще акцентироватся на этом?



offtop

Дело не в этом. А в том что в большенстве школ/вузов еще вполне удачно практикуется программирование именно на 16 компиляторах ибо для изучения основ алгоритмического программирования большего не требуется. Я уверен что ты в курсе.

Ради спортивного интереса скачай BP7 с нашего сайта и попробуй откомпилировать свою программу.Естествеено это все можно исправить, но темне менее, задачи выложенные в этом разделе должны компилироваться на 16 компиляторах паскаля TP, BP.э

зы Мое сообщение можно не комменитровать, если очень хочетсяб в ПМ, дабы не развонидть ненужную полемику.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.