Дали новую тему, текстовые файлы. Давали студенты и никто из группы ничего не понял... А задачи нужно сдать завтра. Помогите хоть с какими-нибудь двумя!!!
1. Дан текстовый файл, содержащий целые числа. Найти • Арифметическое среднее чисел в файле; • Номер максимального элемента в файле; (решена)
2. Дан текстовый файл, содержащий строки. Найти самые короткие строки. (решена)
3. Даны два текстовых файла. Записать в третий только те строки, которые есть и в первом и во втором файлах.
4. Даны два файла А и В(тип элементов одинаковый). Поменять местами содержимое этих файлов. Использовать процедуру Rename не разрешается.
Заранее спасибо!!!
klem4
23.03.2006 22:52
FAQ : Файлы + поиск по форуму, все решалось неоднократно.
Ждешь готового решения ? Делай сам, будут ошибки мы исправим.
Clerick
23.03.2006 23:20
Цитата(klem4 @ 23.03.2006 20:52)
FAQ : Файлы + поиск по форуму, все решалось неоднократно.
Спасибо!!!
Цитата
Ждешь готового решения ? Делай сам, будут ошибки мы исправим.
Проблема в том, что с данной темой ни разу не сталкивался и в принципе не знаю что делать...
Но есть ссылка!!! Почитаем, подумаем, поделаем...
Почитали, подумали и ни к чему не пришли... Можно хотя бы одну решить, в качестве примера?(понимаю, что наглею, но желательно бы что-нибудь из первых двух)
Ozzя
24.03.2006 13:12
Цитата
Можно хотя бы одну решить, в качестве примера?
Если только в качестве примера
Цитата
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
24.03.2006 13:14
Держи первое, дабьше делай сам.
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;
whilenot(eof(f)) dobegin// пока не достигнут конец файла
readln(f, n); // читаем число
inc(count); // увеличиваем счетчик
sr := sr + n; // увеличиваем сумму
end;
close(f); // завершаем раюоту с файлом
if count <> 0thenbegin// считаем среднее арифметическое
sr := sr / count;
writeln('Sr = ', sr : 3 : 3);
writeln('Count = ', count);
endelse writeln('Oops, count = 0'); // файл был пуст
end.
firts.txt :
1 2 7 0 5
Sr = 3.0 count = 5;
Ozzя
24.03.2006 13:18
Цитата
1. Дан тестовый файл,
Опечатка? текстовый?
Хм .. а я даже и не заметил Видимо да ...
Clerick
24.03.2006 18:48
Спасибо!!! И извиняюсь за ошибку!!!
Наткнулся на другую задачу и застрял... Дана матрица 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:=1to n dobeginfor j:=1to m dobegin
g[i,j]:=random (b-a)+a;
Write (g[i,j]:3);
end;
Writeln;
end;
assign (f, 'text.txt');
for i:=1to n dobeginfor j:=1to m dobegin rewrite (f);
Writeln (f, g[i,j]);
end;
end;
Readln;
end.
А она в файл не записывает... В чем ошибка?
Clerick
24.03.2006 19:13
Цитата(klem4 @ 24.03.2006 11:14)
firts.txt :
1 2 7 0 5
Sr = 3.0 count = 5;
А если я в одной строке два числа или больше ставлю?
Ozzя
24.03.2006 19:31
Цитата
for j:=1 to m do begin rewrite (f);
Ты внутри цикла каждый раз уничтожаешь файл и создаешь его заново. Вынеси за цикл:
rewrite (f);
for i:=1to n dofor j:=1to m do
Writeln (f, g[i,j]);
Цитата
А если я в одной строке два числа или больше ставлю?
Тогда усложнится процедура чтения и обработки файла. Зачем нужны лишние хлопоты?
Clerick
24.03.2006 19:44
Цитата(Ozzя @ 24.03.2006 17:31)
Вынеси за цикл:
Вынес и все равно файл пустой остается...
Цитата
[Тогда усложнится процедура чтения и обработки файла. Зачем нужны лишние хлопоты?
Так интересно же как это будет выглядеть!!! А с другой стороны, допустим, файл такой дали. Тогда что делать?
Ozzя
24.03.2006 20:06
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:=1to n dofor j:=1to m do
g[i,j]:=random (b-a)+a;
assign (f, 'c:\bp\text.txt');
rewrite (f);
for i:=1to n dofor j:=1to m do
Writeln (f, g[i,j]);
close(f);
readln;
end.
Clerick
24.03.2006 20:24
О теперь работает!
Close (f); забыл поставить...
Цитата(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я
24.03.2006 20:33
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:=1to n dofor j:=1to m do
g[i,j]:=random (b-a)+a;
assign (f, 'c:\bp\text.txt');
rewrite (f);
for i:=1to n dobeginfor j:=1to m do
Write (f, g[i,j],' ');
writeln(f);
end;
close(f);
readln;
end.
Clerick
24.03.2006 20:44
Теперь все одну строчку...
Ozzя
24.03.2006 21:11
Все нормально отрабатывает
Clerick
24.03.2006 22:54
Все в норме!!! Пропустил один оператор...
Возник еще вопрос! Как имея файл со некоторым количеством строк, определить сколько их?
Altair
24.03.2006 23:06
Цитата
Как имея файл со некоторым количеством строк, определить сколько их?
результат (количество строк) после выполнения кода в переменной result (int).
Clerick
25.03.2006 22:14
Если я прав(приближенно), то след. прога должна выводить содержимое файла
uses crt;
var f:text;
j, i, max, c:integer;
s:string;
begin
assign (f, 'text.txt');
reset (f);
whilenot eof(f) dobegin
Readln(f,i);
inc(j);
end;
for i:=1to j dobeginwhilenot eoln(f) dobegin
readln (f,s);
write (s:2);
Writeln;
end; end;
close(f);
end.
А она не выводит. В чем ошибка?
Ozzя
25.03.2006 22:19
uses
crt;
var
f:text;
j, i, max, c:integer;
s:string;
begin
assign (f, 'text.txt');
reset (f);
whilenot eof(f) dobegin
Readln(f,s);
Writeln(s);
inc(j);
end;
close(f);
end.
Clerick
25.03.2006 22:26
Спасибо!!!
Появился вопр. к з.2 можно её решить след. образ. Сосчитать кол-во символов в каждой строке, загнать в массив, а потом сравнить и выявить min? Или можно проще?
Ozzя
25.03.2006 22:33
Можно проще. Сразу при считывании строк из файла находи минимальные из них.
Clerick
25.03.2006 22:43
Считывание строк в цикле?
Ozzя
25.03.2006 22:48
Ну да
whilenot eof(f) dobegin
readln(f,s);
n:=length(s);
if n< min then
min:=n;
....
end;
мисс_граффити
25.03.2006 22:59
"найти самые короткие строки" - это вывести их номера или их сами?
Clerick
25.03.2006 23:22
Цитата(мисс_граффити @ 25.03.2006 20:59)
вывести их номера или их сами
Номера!
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);
whilenot eof(f) dobegin
readln(f,s);
n:=length(s);
if n<min then
min:=n;
end;
close(f);
Writeln (min);
readln;
end.
она тебе выводит длину минимальной строки... а чему она должна быть равна? у меня с тем же текстом выводит 3: то есть правильно (последняя строка: 3 пробел 1). может, у тебя там еще какой-то символ?
Clerick
25.03.2006 23:49
Цитата(мисс_граффити @ 25.03.2006 21:23)
у меня с тем же текстом выводит 3: то есть правильно (последняя строка: 3 пробел 1). может, у тебя там еще какой-то символ?
Да нет вроде ничего нет. Хотя сейчас посмотрю.
Все теперь все в норме!
А как вывести номер строки?
мисс_граффити
26.03.2006 0:16
для этого его надо отслеживать. например, делай так, как изначально собирался - через массив и выводи номера минимальных элементов. только здесь возникнет вопрос по поводу размера массива...
hardcase
26.03.2006 1:10
Нужно просто считать итерации и запоминать итерацию, на которой обнаружена самая короткая сторока.
кроме того у вас ошибка вот здесь:
assign (f, 'text.txt');
reset (f);
Readln (f,s); //уберите эту строку! вдруг файл пустой? - будет ошибка
min:=length(s); // замените на min:=MaxInt; или на min:=$7FFFFFFF;
мисс_граффити
26.03.2006 2:48
Цитата(hardcase @ 25.03.2006 21:10)
Нужно просто считать итерации и запоминать итерацию, на которой обнаружена самая короткая сторока. кроме того у вас ошибка вот здесь...
у нас по условию таких строк несколько. сколько именно - заранее не знаем.
по-хорошему, надо проверять, есть ли вообще этот файлик ;)
hardcase
26.03.2006 3:16
Цитата(мисс_граффити @ 25.03.2006 22:48)
у нас по условию таких строк несколько. сколько именно - заранее не знаем.
Так в чём проблема? Формируем список, каждый элемент которого будет содержать индекс строки. Вот и алгоритм: Если нашли строку короче, чем были до этого, то гробим предидущий список, и создаём новый (из 1 элемента) который заносим текущй индекс, если строка по длине такая же, то добавляем в текущий список.
В конце просто выбрасываем этот список на печать.
program FindAllMinStrings;
type
PElement = ^TElement;
TElement = recordindex: integer; //здесь будет храниться номер строки
str: string; // сама строка
next: PElement; //следующий элемент в списке
end;
const InputFileName = 'test.txt';
var lst: PElement = nil;
// процедура будет разрушать список - возвращаем память
procedure KillList;
// обычный рекурсивный проход по элементам списка
// можно, конечно, и в цикле, но я привык к SML
procedure Kill(El: PElement);
beginif El = nilthen 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);
beginif El = nilthen 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);
whilenot EOF(InputFile) dobegin
ReadLn(InputFile, curstr);
curlen:=Length(curstr);
if curlen < minlen thenbegin// нашли строку короче, чем уже имеем - гробим список
KillList;
// и строим его заново
Cons(NewElement(i, curstr))
endelseif curlen = minlen thenbegin// нашли строку по длине совпадающую с текущим минимумом
// благополучно запоминаем её и индекс
Cons(NewElement(i, curstr))
end;
inc(i); // не забываем считать строки :-)
end;
Close(InputFile);
// печатаем что есть
PrintList;
// и чистим память (хотя можно и без этого)
KillList;
end.
Вот собсна. Делфю грузить неохота, но должно работать.
мисс_граффити
26.03.2006 13:07
Цитата(hardcase @ 26.03.2006 0:16)
Вот собсна. Делфю грузить неохота, но должно работать.
Возможно... хотя у меня делфи на Assign ругается - предпочитает AssignFile. Но проблема в том, что списки в школе и в неспециализированных вузах не дают обычно. Сомневаюсь, что Clerick с ними сталкивался... соответственно, так решенная задача может вызвать подозрения препода.
Clerick
26.03.2006 15:00
Цитата(мисс_граффити @ 26.03.2006 11:07)
Но проблема в том, что списки в школе и в неспециализированных вузах не дают обычно. Сомневаюсь, что Clerick с ними сталкивался... соответственно, так решенная задача может вызвать подозрения препода.
Это предыдущая тема, которую мы прошли(физмат профиль в школе)! Но решали лишь элементарные задачи. Поэтому большая просьба к Hardcase: поясни свой код!!!
Зы: мой компилятор BP7
hardcase
26.03.2006 15:27
Коментарии добавил. (вроде там и комментировать-то нечего - чай не 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
26.03.2006 22:13
Цитата(klem4 @ 26.03.2006 13:27)
BP и TP это не откомпилируют 100 %, hardacase, тебе на кажется что раздел 32 битные компиляторы находится в другом месте ?
Не откомпилируют что?
hardcase
26.03.2006 22:23
Не знаю- не знаю, всё должно скомпилиться - вот посмотрел предыдущий вариант решения задачи - Clerick это скомпилит.
Только при чём тут вообще разрядность? На дворе 2006 год! Тут уже переходят на 64 разрядные машины. Мне казалось, что 16-бит компилеры благополучно вышли из употребления (померли) ещё 10 лет назад... Зачем вообще акцентироватся на этом?
Clerick
26.03.2006 22:48
Начались проблемы...
var lst: PElement ; = nil; Требует поставить ; в указанном месте...
После того как ставлю, требует begin, а дальше говорит error in statement....
hardcase
26.03.2006 23:13
А проинициализировать переменные в begin .. end - не светит?
Clerick
27.03.2006 0:14
Что значит проинициализировать и как это сделать?
hardcase
27.03.2006 1:00
Я не знаю, что такое BP7, он похоже не поддерживает инициализацию переменных при объявлении
Код
var lst: PElement = nil;
поэтому стоит заменить на
Код
var lst: PElement; ... begin lst:=nil; .... Assign(...) ... end.
с другими переменными - аналогично
Clerick
27.03.2006 1:07
Цитата(hardcase @ 27.03.2006 0:00)
Я не знаю, что такое BP7
Если мне не изменяет память то это Borland Pascal 7.
klem4
27.03.2006 2:10
Цитата(hardcase @ 26.03.2006 19:23)
Не знаю- не знаю, всё должно скомпилиться - вот посмотрел предыдущий вариант решения задачи - Clerick это скомпилит.
Только при чём тут вообще разрядность? На дворе 2006 год! Тут уже переходят на 64 разрядные машины. Мне казалось, что 16-бит компилеры благополучно вышли из употребления (померли) ещё 10 лет назад... Зачем вообще акцентироватся на этом?
offtop
Дело не в этом. А в том что в большенстве школ/вузов еще вполне удачно практикуется программирование именно на 16 компиляторах ибо для изучения основ алгоритмического программирования большего не требуется. Я уверен что ты в курсе.
Ради спортивного интереса скачай BP7 с нашего сайта и попробуй откомпилировать свою программу.Естествеено это все можно исправить, но темне менее, задачи выложенные в этом разделе должны компилироваться на 16 компиляторах паскаля TP, BP.э
зы Мое сообщение можно не комменитровать, если очень хочетсяб в ПМ, дабы не развонидть ненужную полемику.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.