Дали новую тему, текстовые файлы. Давали студенты и никто из группы ничего не понял... А задачи нужно сдать завтра. Помогите хоть с какими-нибудь двумя!!!
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;
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я
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:=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
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:=1 to n do for j:=1 to 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:=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
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:=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
24.03.2006 20:44
Теперь все одну строчку...
Ozzя
24.03.2006 21:11
Все нормально отрабатывает
Clerick
24.03.2006 22:54
Все в норме!!! Пропустил один оператор...
Возник еще вопрос! Как имея файл со некоторым количеством строк, определить сколько их?
Altair
24.03.2006 23:06
Цитата
Как имея файл со некоторым количеством строк, определить сколько их?
while not eof(f) do begin readln(f,s); inc(result) end;
результат (количество строк) после выполнения кода в переменной 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); 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я
25.03.2006 22:19
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
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
Ну да
while not eof(f) do begin 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); 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.
она тебе выводит длину минимальной строки... а чему она должна быть равна? у меня с тем же текстом выводит 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 = 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.
Вот собсна. Делфю грузить неохота, но должно работать.
мисс_граффити
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.э
зы Мое сообщение можно не комменитровать, если очень хочетсяб в ПМ, дабы не развонидть ненужную полемику.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.