PDA

Просмотр полной версии : Файлы



Justice
16.03.2007, 23:04
помогите разобраться с задачей: надо создать файл и добавить в конец файла символы end.

uses crt;
type tbook=record
tekst:string;
end;
tfile=file of tbook;
var
myfile:tfile;
newrecord:tbook;
begin
assign(myfile,'book.dat');
rewrite(myfile);
with newrecord do begin
writeln('vvedit tekst'); readln(tekst);
end;
close(myfile);
reset(myfile);
begin clrscr;
with newrecord do
seek(myfile,filesize(myfile)); write(myfile,?);
readln
end.

вроде все правильно писала, но не знаю что писать там где writeln(myfile, ... )

Колядин Максим
17.03.2007, 01:29
uses crt;
type tbook=record
tekst:string;
end;
tfile=file of tbook;
var
myfile:tfile;
newrecord:tbook;
begin
assign(myfile,'book.dat');
rewrite(myfile);
with newrecord do begin
writeln('vvedit tekst'); readln(tekst);
end;
close(myfile);
reset(myfile);
begin clrscr;
with newrecord do
seek(myfile,filesize(myfile)); write(myfile,?);
readln
end.
Ты, наверное, запутала сама себя, создав много лишних "проблем"-); Я бы решил эту задачу так:


uses crt;
var
myfile: file;
tekst: string;
begin
assign(myfile,'book.dat');
rewrite(myfile);
close(myfile);
tekst:='end';
reset(myfile);
seek(myfile,filesize(myfile));
blockwrite(myfile, tekst, 1);
end.

Вот с текстовым файлом:


uses crt;
var f: text;
s: string;
begin
clrscr;
s:='end';
assign(f, 'book.dat'); rewrite(f);
append(f);
write(f,s);
close(f);
end.

Justice
17.03.2007, 12:19
Я бы решил эту задачу так:


uses crt;
var
myfile: file;
tekst: string;
begin
assign(myfile,'book.dat');
rewrite(myfile);
close(myfile);
tekst:='end';
reset(myfile);
seek(myfile,filesize(myfile));
blockwrite(myfile, tekst, 1);
end.

Вот с текстовым файлом:


uses crt;
var f: text;
s: string;
begin
clrscr;
s:='end';
assign(f, 'book.dat'); rewrite(f);
append(f);
write(f,s);
close(f);
end.


а если все же решать эту задачу с типовым файлом?

Колядин Максим
17.03.2007, 19:46
Я точно утверждать ничего не буду, но по-моему компилятор всегда будет выдавать ошибку во write(myfile, ?), так как переменная var myfile: tfile не является текстовой, а процедура write(f,...) (var f: text) используется только как запись в типизированный текстовый файл. BlockWrite здесь тоже неподойдёт - это только для нетипизорованного типа file. Возможно, компилятор всегда будет писать: "Tip mistmach" - потому что он не знает что нужно твоему type tbook=record tekst:string; end; tfile=file of tbook; var myfile:tfile;
P.S Чем тебя без type не устраивает?...

Хыиуду
19.03.2007, 10:09
Если я правильно понял, задание можно сформулировать так: "Создать файл с текстом "end.""


var f:text;
begin
assign(f,'books.dat');
rewrite(f);
writeln(f,'end');
close(f)
end.

Можно, конечно, rewrite заменить на append, чтобы добавлять ИМЕННО в конец файла, но какой смысл это делать, если создаваемый файл все равно пустой изначально?

BBB
19.03.2007, 10:14
.... так как переменная var myfile: tfile не является текстовой, а процедура write(f,...) (var f: text) используется только как запись в типизированный текстовый файл.
С чего бы это?
Смотрим паскалевский встроенный Help:


Write (procedure)
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
For typed files, writes a variable into a file component. For text files,
writes one or more values to the file

Declaration:
Typed files: procedure Write(F, V1 [, V2,...,Vn ] );
Text files: procedure Write( [ var F: Text; ] P1 [,P2,...,Pn ] );
Так что, write вполне себе бует писать в типированный файл.

Колядин Максим
19.03.2007, 17:15
var f:text;
begin
assign(f,'books.dat');
rewrite(f);
writeln(f,'end');
close(f)
end.
Ну вот не нравится ей (Justice) такой код! Ей хочется сначала создать type tbook=record tekst:string;, потом tfile=file of tbook;, затем var myfile:tfile;.
Justice, что у тебя за преподователь, который задаёт в конец пустого файла записать "end", не разрешает использовать функции - только процедуры..?

BBB
19.03.2007, 17:24
помогите разобраться с задачей: надо создать файл и добавить в конец файла символы end.
................................
вроде все правильно писала, но не знаю что писать там где writeln(myfile, ... )Вместо '?' надо писать переменную того же типа, "чьего типа" объявлен файл. В данном случае - tbook:


uses crt;
type tbook=record
tekst:string;
end;
tfile=file of tbook;
var
myfile:tfile;
newrecord:tbook;
begin
assign(myfile,'book.dat');
rewrite(myfile);
with newrecord do begin
writeln('vvedit tekst'); readln(tekst);
end;
clrscr;

close(myfile);
reset(myfile);

seek (myfile, filesize(myfile));
write (myfile, newrecord);

readln;
end.

Хыиуду
20.03.2007, 10:34
Думаю, без seek (myfile, filesize(myfile)); можно обойтись. Все равно файл изначально пустой.

BBB
20.03.2007, 10:46
Думаю, без seek (myfile, filesize(myfile)); можно обойтись. Все равно файл изначально пустой.Я так понимаю, что это УЧЕБНАЯ задача. Поэтому и такие "странные" требования. То есть, как я полагаю, цель задачи - не получить практически используемую программу, а освоение определенных возможностей (операторов) языка программирования.
Поэтому, раз в условии сказано "добававить в конец", то нужно присутствие оператора, устанавливающего текущий указатель на конец файла.
;-)

Хыиуду
20.03.2007, 12:04
Не перестаю поражаться, как преподаватели дают студентам задачи, полностью убивающие программерский стиль мышления! Хорошо еще если в стиле: "Дан гвоздь, надо забить его в стену. Можете воспользоваться микроскопом", а то зачастую "Даны гвоздь и микроскоп, забейте в стену одно с помощью другого"!

BBB
20.03.2007, 12:57
Не перестаю поражаться, как преподаватели дают студентам задачи, полностью убивающие программерский стиль мышления! Хорошо еще если в стиле: "Дан гвоздь, надо забить его в стену. Можете воспользоваться микроскопом", а то зачастую "Даны гвоздь и микроскоп, забейте в стену одно с помощью другого"!Не уверен, что это корректное сравнение.
А как еще продемонстрировать использование (закрепить на практике) типированных файлов? Дается задание с указанием применить "изучаемый материал" (т.е. в данном случае - типированных файлов).
Еще раз: не путайте учебную задачу (программу) с практической.

Для сравнения. Существуют шахматные задачи. Ну, типа, "белые начинают и выигрывают", "белые начинают и дают мат в два хода". Так вот, во многих задач расстановка фигур такова, что она вообще вряд ли когда-нибудь возникнет в реальной партии.
Далее, сущеcтвует род шахматных задач "кооперативный мат". Т.е. когда и черные, и белые играют "на одну руку". Чего в реальной партии уж точно не бывает. И, тем не менее, подобные задачи составляются и их решают. И никто не говорит "Ну что за идиот такую задачу поставил, ведь в жизни такого не бывает!"

Хыиуду
20.03.2007, 14:14
Ну тогда сделали бы file of record: name:string;phone:longint; end;, уже было бы логичнее и практичнее. А то с помощью двух пользовательских типов записать в файл текст-константу - имхо, не очень помогает обучению программированию. У меня после этого возник бы закономерный вопрос: "А зачем в этой программе эти два пользовательских типа?"

BBB
20.03.2007, 14:34
Ну тогда сделали бы file of record: name:string;phone:longint; end;, уже было бы логичнее и практичнее.По-моему, так как раз менее наглядно (менее структурированно). Все свалено "в одну строку". Начинающий только будет путаться и при чтениитакого текста, и при написании.
(Я о НЕобъявлении отдельного типа на record).

У меня после этого возник бы закономерный вопрос: "А зачем в этой программе эти два пользовательских типа?"Для наглядности, стройности и читаемости текста программы.

Хыиуду
20.03.2007, 15:48
Ну, свалил все в одну строку я, люблю иногда емкость кода в ущерб читаемости сделать ;) А вот насчет всего остального - куда-то мы ушли в сторону киевских дядек и заросших бузиной огородов.

Колядин Максим
20.03.2007, 21:50
Не уверен, что это корректное сравнение.
А как еще продемонстрировать использование (закрепить на практике) типированных файлов? Дается задание с указанием применить "изучаемый материал" (т.е. в данном случае - типированных файлов).
Еще раз: не путайте учебную задачу (программу) с практической.
Может быть ты и прав, но в данном случае я на стороне Хыиуду. С фразой "Не перестаю поражаться, как преподаватели дают студентам задачи, полностью убивающие программерский стиль мышления!" - полностью согласен. Наверное, это просто неудачный пример использования типов, - они здесь совсем не нужны. Ну, научит её преподаватель использовать типы к таким задачам - а она и начнёт применять их ко всем "ненуждающимся", тем самым, наполняя код ненужными действиями и затемняя свой разум.
Однажды бывал я на сайте для начинающих программистов и увидел там нечто очень страшное. "Грязные коды"! Здесь самая простая задача полна совсем ненужных переменных, ненужных функций и прочего. Скорее всего, у автора сайта http://www.tpxexe.narod ru был примерно такой же преподаватель, как у Justcle. По его мнению, задача с условием "В строке убрать лишние пробелы" решается так:


program z1;
uses crt;
label 1,2,3,4;
var a,b:string; i,j,n,max,k:integer; x,s:array[1..100] of string;
begin
clrscr;
readln(a);
i:=1;
n:=1;
for j:=1 to 100 do
begin
x[j]:=''; s[j]:='';
end;
while i<=length(a) do
begin
if a[1]=' ' then goto 3 else goto 2;
2:if (a[i]=' ') and (a[i+1]<>' ') then n:=n+1;
repeat
x[n]:=x[n]+a[i];
i:=i+1;
if a[i]=' ' then goto 2;
if i>length(a) then goto 4;
until a[i]<>' ';
3:repeat
if a[i]<>' ' then goto 2;
i:=i+1;
if i>length(a) then goto 4;
until a[i]=' ';
end;
4:for j:=1 to n do
for i:=1 to length(x[j]) do
if x[j][i]<>' ' then s[j]:=s[j]+x[j][i];
b:='';
for i:=1 to n do
b:=b+s[i]+' ';
writeln(b);
readkey;
end.

Согласитесь, очень страшный код! И автор сайта здесь не хотел объяснить случаи использования меток - здесь все такие решения. Рассмотрим ещё одну задачу с этого же сайта, под названием "Определить, является ли заданное число степенью двойки?" (ссылка http://www.tpxexe.narod.ru/017.html):


program z1;
uses crt;
label 1;
var a,i,k:integer;
begin
writeln('Введите число ');
readln(a);
k:=0; i:=0;
while a>1 do
begin
i:=a mod 2;
a:=a div 2;
if i<>0 then begin k:=1; goto 1; end;
end;
1:if k=0 then writeln('yes!')
else
writeln('no');
readkey;
end.
{http://www.tpxexe.narod.ru/017.html}

Опять метки! Ведь эту задачу можно было решить гораздо проще:


var a,b:integer;
begin
readln(a);
b:=2;
while b<a do b:=b*2;
if b<>a then write('Не является') else write('Является');
readln;
end.

После просмотра этого сайта, у меня сложилось впечатление, что преподаватель автора хотел объяснить ему, что такое лабелы, и в качестве примера давал ему задачи, где они совершенно не уместны! И вот результат... - они всегда и везде!!! Так что, я всеми этими фактами хочу поддержать мнение Хыиуды (надеюсь, это существительное склоняется-);), а именно, предложение о том, что преподаватели своими "тупыми" примерами использования, в данном случае типов, убивают программерский стиль мышления.

Хыиуду
21.03.2007, 10:54
Колядин Максим, не склоняется ;) В остальном согласен. У нас многие преподаватели вообще требовали обходиться без меток именно потому, что они убивают структурированность программы.
Что касается задачи про степень двойки - тут все можно еще сократить.
repeat
if odd(x) then begin writeln('Не является'); exit;end;
x:=x div 2;
until x=1;
writeln('Является');

BBB
21.03.2007, 12:18
... У нас многие преподаватели вообще требовали обходиться без меток именно потому, что они убивают структурированность программы....Ага, у нас такое тоже было. И, в принципе, они, конечно, правы (т.е., "метки убивают структурированность"). Хрен сразу найдешь все входы и выходы в/из процедуры :)

Колядин Максим
21.03.2007, 15:04
Да, входы и выходы из процедур с и правда не найдёшь... К тому же, не единичный случай, когда компилятор по неизвестной причине выдаёт ошибку, где написано что метка находится вне текущего блока. Решение проблемы – перезагрузка программы или копирование кода в новый документ.
Вот небольшая статья о вреде использования меток:
_______________________
В языке программирования Паскаль, и следовательно в системе программирования Turbo Pascal 7.0 поддерживаются современные методологии
проектирования программ (нисходящее, модульное проектирование, структурное программирование).
Концепция структурного программирования пришла в своё время на
смену линейному программированию, реализованному в таких языках программирования как Бейсик. В настоящее время наиболее применяемой является структурная концепция программирования. В структурном программировании принят естественный порядок выполнения программы: все операторы выполняются последовательно один за другим в том порядке, как они записаны. Для структурированных программ характерны легкость отладки и
корректировка, низкая частота ошибок.
Описанный в данной лабораторной работе безусловный оператор,
строго говоря, просто "запрещён" структурной концепцией как грубо нарушающий её основные принципы, и является "атавизмом" оставшимся как
воспоминание о более примитивном линейном программировании. Система
программирования Turbo Pascal 7.0 обладает достаточно мощными средствами, позволяющими полностью отказаться от применения этого оператора.
Учитывая все описанные выше причины, настоятельно рекомендуется
вообще отказаться от использования оператора безусловного перехода,
или свести его применение к минимуму. Если же вы всё-таки решили применить его в своей программе, то вы должны помнить, что использовать этот оператор следует крайне осторожно. Широкое его применение без особых на то оснований ухудшает понимание логики работы программы. Безусловный переход можно осуществлять далеко не из каждого места программы. Так, нельзя с помощью этого оператора перейти из основной программы в подпрограмму или выйти из подпрограммы, не рекомендуется осуществлять переход внутрь структурированного (составного) оператора, т.к. он может дать неправильный результат, с помощью оператора перехода, расположенного вне условного оператора или оператора цикла, нельзя перейти внутрь этого условного оператора или оператора цикла и т.д.

BBB
21.03.2007, 15:55
Вот небольшая статья о вреде использования меток:
_______________________
..................
Безусловный переход можно осуществлять далеко не из каждого места программы. Так, нельзя с помощью этого оператора ... выйти из подпрограммы....Ну, умельцы-то это делали. При помощи ассемблера сохраняя и востанавливая, так сказать, "образ текущего состояния" (читая - значения регистров :))
У меня даже исходник еще тех времен имеется :)

UPD. Хотя, конечно, строго говоря, это не оператор goto, это уже пара процедур. Но "логический смысл" их - не что иное, как "длинный goto".

Хыиуду
22.03.2007, 09:51
Ну то ассемблер, там вообще все по сути строится на трех операторах Дейкстры (кажется) - присвоении, ветвлении и безусловном переходе. Спасибо хоть там loop есть, и то хлеб. А в языках уровня Паскаля и выше без меток все же лучше обойтись.
Тему, думаю, пора переносить.

Хыиуду
27.04.2007, 11:28
К тому же, не единичный случай, когда компилятор по неизвестной причине выдаёт ошибку, где написано что метка находится вне текущего блока.

Обычно это бывает, когда метка находится в цикле (особенно это относится к циклам с параметром) или в подпрограмме, а goto - вне их.

Колядин Максим
27.04.2007, 17:41
Обычно это бывает, когда метка находится в цикле (особенно это относится к циклам с параметром) или в подпрограмме, а goto - вне их.
Если бы... (читай цитированное тобой сообщение дальше)