Файлы Турбо Паскаля

Начнём этот раздел с небольшого замечания о том, что часто бывает удобно отдельные виды обработки файлов оформлять как отдельные процедуры. В число формальных параметров таких процедур обычно включается или имя файловой переменной (обязательно передоваемой по ссылке, т.е. VAR !), или стринг, определяющий физическое имя обрабатываемого в процедуре файла.

В первом случае (передаётся файловая переменная) файл может описываться и привязываться (возможно, и открываться) в главной программе, а во втором - всё это может делаться в подпрограмме, в которой соответствующая файловая переменная локальна.

В качестве примера, воспроизведём здесь вариат уже представленного на сайте решения следующей сформулированной мною на лекции задачи:

Задача "Треугольник". Написать программу, которая формирует по заданному натуральному N, текстовый файл следующей треугольной структуры :
1
2 3
4 5 6
7 8 9 10
...
Каждая следующая строка этого файла содержит на один элемет больше предыдущей, а последней считается та, в которую попадёт заданное натуральное N.

  1. Program txtFileOut;
  2.    // обошлись без переменных!
  3.     procedure triangle(n:integer; var f: Text);
  4.         Var i, inLn, lnCount: LongInt;
  5.     Begin
  6.         i:=1;  // значение первого элемента
  7.         inLn:=1; // число элементов в 1-й строке
  8.         Repeat
  9.            For lnCount:=1 to inLn Do Begin  // формируем строку
  10.               Write(f,i:3); Inc(i)
  11.            End;
  12.            WriteLn(f); // к следующей строке ...
  13.            Inc(inLn); //... в которой будет на один элемент больше
  14.         Until i>n;
  15.     End;
  16.  
  17. Begin
  18.    triangle(20, output);
  19.    readln;
  20. End.

Заметьте, для проверки решающей задачу процедуры в главной программе использован стандартный текстовый файл output. Это позволяет обойтись без его описания, привязки и открытия в главной программе. Правда, результат мы получим на экране, а не на диске. Запустите и убедитесь что всё работает!
Теперь измените главную программу с тем, чтобы файл выводился на диск. И снова проверьте!

Вот несколько типовых задач, понимание решения которых гарантирует успех в контрольной работе по данной теме:

Задача fl1. Дана входная последовательность натуральных чисел, завершающаяся нулём. Написать процедуру, позволяющую ввести эту последователность с клавиатуры и переписать её в выходной файл, который можно было бы далее просмотреть с помощью Блокнота. Дополнить решение вызывающей программой.

Задача fl2. В Блокноте набран и сохранён под именем 'ttt.txt' текстовый файл, содержащий по одному символу (Char) в каждой строке. Длина файла не превышает 255. Написать программу, которая читает этот файл как типизированный и формирует объединяющий все его символы стринг.

Задача fl3. В Блокноте набран и сохранён под именем 'D.txt' текстовый файл, содержащий по одному символу (Char) в каждой строке. Длина файла произвольна. Написать программу, которая читает этот файл и формирует на его основе файл 'R.txt' в котором символы исходного файла расположены в обатном порядке.

Задача fl4. Описать функцию, которая по данному текстовому файлу определяет число содержащихся в ней строк.

Задача fl5.Для задаваемых M, N <= 20 сформировать матрицу A(M,N) из случайных натуральных значений (меньших ста) и вывести её построчно (т.е. в "естественном" виде), в текстовый файл. Проверить результат вывода в Блокноте.

Задача fl6.Матрицу, сформированную в задаче fl5 ввести из файла и вывести в транспонированном виде на экран.

Вика.

И копирование и сравнение файлов только поэлементное.

спасибо,также прочитав

спасибо,также прочитав литературу уже разобралась:-)

Валерий Шахамболетович,

Валерий Шахамболетович, почему файле печатаются не числа, а просто знаки, если :

  1. program crtFL;
  2.   var f:file of Integer;
  3.     i,n:LongInt;
  4.     x:integer;
  5. begin
  6.   Assign(f,'myFL.txt');
  7.   Rewrite(f);
  8.   write('n='); readln(n);
  9.   for i:=1 to n do begin
  10.     readln(x); writln(f,x);
  11.   end;
  12.   close(f);
  13.   end.

Но печатает, когда:
  1. program crtFL;
  2.   var f:file of char;
  3.     i,n:char;
  4.     x:char;
  5. begin
  6.   Assign(f,'myFL.txt');
  7.   Rewrite(f);
  8.   write('n='); readln(n);
  9.   for i:=chr(1) to n do begin
  10.     readln(x); write(f,x);
  11.   end;
  12.   close(f);
  13.   end.
(однако во втором случае программа даже внимания на правую границу цикла не обращает и продолжает запрашивать числа);
Подскажите, где ошибка.Спасибо

Ксюша

В первой реализации:
во второй строке объявлен ТИПИЗИРОВАННЫЙ ФАЙЛ(!!!):(а вывод идёт в текстовый файл(!?!?!?))
тогда нужно было так (для вывода в текстовый файл)

  1. ....
  2.  var f:text
  3. ....

Реализация(для вывода в типизированный файл) :

  1. program crtFL;
  2.   var f:file of Integer;
  3.     i,n:LongInt;
  4.     x:integer;
  5. begin
  6.   Assign(f,'myFL.dat'); // привязка
  7.   Rewrite(f); // открытие для записи
  8.   write('n=');
  9.   readln(n);
  10.   for i:=1 to n do begin
  11.     readln(x); // прочитали число
  12.    write(f,x);// записали его в файл
  13.   end;
  14.   close(f);// закрыли файл после записи
  15.   reset(f); // открыли файл для чтения
  16.   while not(eof(f)) do begin   // пока не конец файла
  17.    read(f,x); // читаем из файла  х
  18.    write(x:2);  // выводим на дисплей
  19.   end;
  20.   close(f);
  21. end.

..действительно,Спасибо) а

..действительно,Спасибо) а начиная с 16 строки-это еще и просто вывод на дисплей в прог-е,а не просто в файл только?

Да

для проверки , чтобы убедится что всё хорошо работает :)

а почему во втором моем коде,

а почему во втором моем коде, прог-а не обращает внимание на правую границу цикла?

Ксюша

  1. ....
  2.  for i:=chr(1) to n do begin
  3. ...

chr(x) - дает результат символ с кодом х
в твоем примере символ с кодом (1) находится в начале Ascii таблицы

Вариант решения ...

  1. program crtFL;
  2.  type intFile = file of integer;
  3.  var f:intFile;
  4.      s:string;
  5.  procedure WriteFile(var f:intfile;s:string);
  6.   var i,n,x:longint;
  7.  begin
  8.   Assign(f,s); // привязка
  9.   Rewrite(f); // открытие для записи
  10.   write('n=');
  11.   readln(n);
  12.   for i:=1 to n do begin
  13.    write('x = ');
  14.    readln(x); // прочитали число
  15.    write(f,x);// записали его в файл
  16.   end;
  17.   close(f);
  18.  end;
  19.  procedure KontrolVivod(var f:intfile; s:string);
  20.    var x:integer;
  21.  begin
  22.    Assign(f,s);// привязка
  23.    reset(f); // открыли файл для чтения
  24.    while not(eof(f)) do begin   // пока не конец файла
  25.     read(f,x); // читаем из файла число
  26.     write(x:2);  // выводим его на дисплей
  27.    end;
  28.    close(f);
  29.  end;
  30. begin
  31.   write('name of file: ');
  32.   readln(s);
  33.   WriteFile(f,s);
  34.   KontrolVivod(f,s);
  35. end.

Никита, у Вас в параметрах

Никита, у Вас в параметрах подпрограмм избыточность. Достаточно передавать в подпрограмму либо уже привязанную файловую переменную, либо имя физического файла, т.е. стринг (тогда файловая переменная локализуется в подпрограмме и там же делается привязка).

Здравствуйте!

Прошу помочь.
Задача. Все буквы от а до z напечатать по две в каждой строке:
а) используя текст. файл;
б) используя типиз. файл;
Вот код задачи пункт а):

  1. program Stroki;
  2.   var f:text;
  3.         i:char;
  4. begin
  5.   assign(f,'ddd.txt');
  6.   rewrite(f);
  7.   for i:='a' to 'z' do begin
  8.     if odd(ord(i)) then writeln(f);
  9.       write(f,i);
  10.   end;
  11.   close(f);
  12. end.

Выводит всё верно ( но как вы говорите:"Если программа выводит результат,еще не значит,что код верный").
Конкретный вопрос с пунктом б).
вот код:
  1. program Stroki1;
  2.   var f:file of byte;
  3.         i:char;
  4. begin
  5.   assign(f,'ddd.byt');
  6.   rewrite(f);
  7.   for i:='a' to 'z' do begin
  8.     if odd(ord(i)) then writeln;
  9.       write(f,ord(i));
  10.   end;
  11.  close(f);
  12. end.

Результат выводит только в одну строку. Объясните ошибку и как это исправить, если writeln нельзя использовать для типизированного файла. Не совсем понятно. Спасибо

Ошибка очевидна и Вы сами о

Ошибка очевидна и Вы сами о ней пишите - в типизированных файлах понятие строки (line) отсутствует и стандартные процедуры типа WriteLN(f) некорректны. Ваша WriteLN (в которой отсутствует указание файла) как известно, работает со стандартным текстовым файлом OUTPUT, т.е. консолью ( дисплеем), на котором и происходит переход в новую строку. К Вашему файлу f (т.е. ddd.typ), очевидно, это никакого отношения не имеет.
Что же делать? Очень просто - САМИМ ПРОГРАММНО выводить в файл нужную комбинацию кодов, которая отвечает за перевод строки.

А первая программа верна.

Может вот так?program

Может, вот так?

  1. program Stroki1;
  2. var f:file of char;
  3.      i:char;
  4. begin
  5.  
  6.   assign(f,'ddd2.byt');
  7.   rewrite(f);
  8.   for i:='a' to 'z' do begin
  9.      if odd(ord(i)) then
  10.        write(f,#10,#13);
  11.        write(f,i);
  12.   end;
  13. close(f);
  14. end.<pre>

А почему бы Вам не проверить,

А почему бы Вам не проверить, Вика?

Проверяла изначально, вроде

Проверяла изначально, вроде бы все верно.

У меня вот что получилось

  1. procedure stroki2(s:string);
  2.  var f:file of char;
  3.      i:char;
  4. begin
  5.   assign(f,s);
  6.   rewrite(f);
  7.   for i:='a' to 'z' do begin
  8.      if odd(ord(i)) then write(f,i)// если код символа нечетный, то записываем  символ  в файл
  9.      else write(f,i,#13);// иначе записываем и переводим "каретку" на новую строку
  10.   end;
  11.   close(f);
  12. end.

И процедура для контрольного вывода:

  1. procedure control(s:string);
  2.  var f:file of char;
  3.      i,j:char;
  4. begin
  5.   assign(f,s);
  6.   reset(f);
  7.   while not(eof(f)) do begin// пока не конец файла ...
  8.    read(f,i,j,#13);// прочитали из файла в переменные i,j и перевели   "каретку" на новую строку
  9.    writeln(i,j);// вывели на дисплей
  10.   end;
  11.   close(f);
  12. end.

спасибо всем.да, #10 и

спасибо всем.да, #10 и #13-подзабыла о них.

ШЕСТЬ ЗАДАЧ по файлам.

ШЕСТЬ ЗАДАЧ по файлам для самостоятельного решения(см. начало данной страницы)

Задача fl1

Задача fl1. Дана входная последовательность натуральных чисел, завершающаяся нулём. Написать процедуру, позволяющую ввести эту последовательность с клавиатуры и переписать её в выходной файл, который можно было бы далее просмотреть с помощью Блокнота. Дополнить решение вызывающей программой.

  1. program fl1;
  2.  var s:string[40];
  3.  
  4.  procedure InFile(s:string);
  5.   var f:text;
  6.       n:word;
  7.  begin
  8.   assign(f,s);// привязка
  9.   rewrite(f);// открытие для записи
  10.   while true do begin // пока истина:
  11.    write('n= ');
  12.    readln(n);// прочитали очередное число
  13.    if n=0 then break; // выход только по break
  14.    write(f,n,' ');// запись числа в файл
  15.   end;//while
  16.   close(f);// закрытие файла
  17.  end; //InFile
  18.  
  19.  begin// главная программа
  20.   write('name of file: ');
  21.   readln(s);// ввод имени текстового  файла
  22.   InFile(s); // процедура ввода в файл
  23. end.

Возьмём паузу...

Не стоит усложнять общую логику лишними If-break конструкциями ради сомнительной экономии одного-двух (или даже более) операторов:

  1. ...
  2. Write('n='); Readln(n);
  3. While n<>0 Do Begin
  4.      writeln(f,n);  
  5.      Write('n='); Readln(n);
  6. End;
  7. ...

Спасибо, Никита. Давайте теперь возьмём паузу. Хотя у меня предчуствие, что ею никто (ну кроме, возможно, Вики или Ксении) не воспользуется...

Хорошо,

я тогда Вам на почту решения отправлю

Добрый день, Валерий

Добрый день, Валерий Шахамболетович! Вот задача fl2.
"В Блокноте набран и сохранён под именем 'ttt.txt' текстовый файл, содержащий по одному символу (Char) в каждой строке. Длина файла не превышает 255. Написать программу, которая читает этот файл как типизированный и формирует объединяющий все его символы стринг."

  1. program fl2;
  2. var f:text;
  3.      y,c:char;
  4.      f1:file of char;
  5. begin
  6. assign(f,'ttt.txt');
  7.  rewrite(f);
  8.  assign(f1,'ttt1.txt');
  9.  rewrite(f1);
  10. //здесь производится заполнение и сохранение текствого файла с символами
  11. ...
  12. //далее...
  13. reset(f);
  14.   while not Eof(f) do begin
  15.       readln(f, y);
  16.       write(f1,y);
  17.   end;
  18.   close(f);
  19.   close(f1);
  20. end.
.
Но проблема в том, что в типизированном файле сформулировано не всё количество символов,хотя в текстовом все верно. Подкажите, в чем ошибка.

Задача fl3.

В Блокноте набран и сохранён под именем 'D.txt' текстовый файл, содержащий по одному символу (Char) в каждой строке. Длина файла произвольна. Написать программу, которая читает этот файл и формирует на его основе файл 'R.txt' в котором символы исходного файла расположены в обатном порядке.

  1. program ReversFl;
  2. var
  3.     f1, f2:text;
  4.     x: char;
  5.     a: array [1..100] of char;
  6.     k, i: integer;
  7.  
  8. begin
  9.     assign (f1, 'D.txt');
  10.     reset (f1);
  11.     k := 1;
  12.     while not eof (f1) do begin
  13.         read (f1, x);
  14.         a[k] := x;
  15.         write (x);
  16.         k := k + 1;// колличество эл-ов в массиве
  17.     end;
  18.     assign (f2, 'R.txt');
  19.     rewrite (f2);
  20.     for i := k-1 downto 1 do begin
  21.         write (f2, a[i]);
  22.         writeln;
  23.     end;
  24.     close (f1);
  25.     close (f2);
  26. end.

с помощью массива и отступы между строками получаются почему-то

и задача fl4.

Описать функцию, которая по данному текстовому файлу определяет число содержащихся в ней строк.

  1. function Str(f:text):integer;
  2. var
  3.     x: char;
  4.     line: word;
  5. begin
  6.     assign(f,'K.txt');
  7.     reset(f);
  8.     line := 0;
  9.     while not Eof(f) do begin
  10.         read(f,x);
  11.         if ord(x) = 13 then begin
  12.             read(f,x);
  13.             line :=line+1;
  14.         end;
  15.     end;
  16.     close(f);
  17.     Str:=line+1;
  18. end.

мне кажется, задачу fl3 можно

мне кажется, задачу fl3 можно решить проще:

  1. program fl3;
  2. var f,f1:text;
  3.      c:char;
  4.      s:string;
  5.      i:byte;
  6. begin
  7.  assign(f,'D.txt');
  8.  rewrite(f);
  9.  assign(f1,'R.txt');
  10.  rewrite(f1);
  11.  s:='';
  12. //здесь циклом формируется файл с одним символом в каждой строке
  13. ...
  14.    s:=s+c;//в цикле к переменной стрингового типа добавляем по одному символу
  15.   end;//завершили цикл
  16.   close(f);
  17.   reset(f);
  18.   for i:=length(s) downto 1 do begin
  19.      writeln(f1,s[i]);
  20.   end;
  21.  writeln(f1);
  22.  close(f);
  23.  close(f1);
  24. end.

Вика

по задаче Fl2:
зачем всё это:

  1.  ...
  2.  assign(f,'ttt.txt');
  3.  rewrite(f);
  4.  assign(f1,'ttt1.txt');
  5.  rewrite(f1);
  6. ...

Ведь в условии сказано, что " в Блокноте набран и сохранён под именем 'ttt.txt' текстовый файл", то есть ФАЙЛ УЖЕ СУЩЕСТВУЕТ

задача fl4 function

задача fl4

  1. function fl4(name:string):byte;
  2.   var f:text;
  3.       n:byte;
  4.       s:string;
  5. begin
  6.  assign(f,name);
  7.  reset(f);
  8.  while not eof(f) do begin
  9.    readln(f,s);
  10.    n:=n+1;
  11.  end;
  12.  write(n);
  13.  close(f);
  14. end;<pre>

Ксения

по задаче fl3:
у тебя описан массив на сто элементов:

  1. ...
  2.  a: array [1..100] of char;
  3. ...

А если в файле будет, например, 101 символ ?(в каждой строке по одному символу(!?))

Вика

по задаче fl3:
можно ещё проще...

и ещё: если в файле будет 257 символов (??) (по одному в каждой строке )
тогда если исходить из твоего кода :

  1. ...
  2. s:=s+c;//в цикле к переменной стрингового типа добавляем по одному символу
  3. ....

в s попадут не все символы (!?)

Вика

по задаче fl4, непонятно для чего в функции идет вывод количества строк ( строка 12)
вместо этого нужно было cделать так:

  1.  function fl4(name:string):byte;
  2.  ...
  3.   fl4:=n;
  4.  end;

тогда в вызывающей программе можно сделать так:

  1.  writeln('количество строк в файле: ',fl4(s));// где s имя файла

задача fl2, может так? var

задача fl2, может так?

  1. var f:file of char;
  2.     c:char;
  3.     s:string;
  4. begin
  5.   assign(f,'ttt.txt');
  6.   reset(f);
  7.   while not (Eof(f)) do begin
  8.     read(f,c);
  9.     s:=s+c;
  10.   end;
  11.   close(f);
  12.   writeln(s);
  13. end.<pre>

Никита,

значит изменю описание массива на большее количество эл-ов. Я ведь только суть показала.

насчет fl3 Никита прав,

насчет fl3 Никита прав, постараюсь исправить

а в fl4,у меня была другая

а в fl4,у меня была другая задумка и немного другая вызывающая программа, Никита:-) но соглашусь, была она у меня на строку больше:-)

Вик, в своей fl4 с 9 по 10

Вик, в своей fl4 с 9 по 10 строку ты сразу в именно прог-е вводишь сторки в файл и считаешь их?

Ксюша, в fl4 я работаю с уже

Ксюша, в fl4 я работаю с уже готовым,ранее созданным и сохраненным файлом. Но можно и в главной программе сформировать файл

Задача fl5

Если я правильно понял условие, то задача 5 выглядит так:

  1. program Record_of_array_ in_the_file;
  2. const lim=30;
  3.   type Ar=array[1..lim,1..lim]of integer;
  4.   var i,j,n,m:integer; f:text; a:ar;
  5. begin
  6. write('Vvedite razmer massiva: ');
  7.   readln(n,m);
  8.   assign(f,'D:/Ar.txt');
  9.   rewrite(f);
  10.   randomize;
  11.    for i:=1 to n do begin
  12.     for j:=1 to m do begin
  13.      a[i,j]:=random(101);
  14.      write(f,a[i,j]:3);
  15.     end;
  16.     write(f,#13,#10);
  17.    end;
  18.   reset(f);
  19.   close(f);
  20. end.

P.S. прошу показать ошибки

а,да..

а,да..

Валентин, я думаю строка 18

Валентин, я думаю строка 18 не требуется...

Виктория

Да, возможно ты права.

Ксения

если объявить массив на большее количество элементов, то всегда есть какой то предел,
Массив здесь не подойдёт

Валентин

матрица размерности (m,n)

Никита

Я их путаю иногда

Виктория

Я думаю, задачу fl2 ты поняла немного неверно. В задаче написано что необходимо прочитать текстовый файл ttt.txt и сформировать стринг, который будет включать символы этого файла. И именно поэтому ограничение у файла 255 символов, совпадающий с ограничением любого стринга. Мне кажется что задача fl2 должна иметь такой вид:

  1. program Characters_in_the_string;
  2.  var f:file of char;
  3.     s:string;
  4.     n:char;
  5.     i:byte;
  6. begin
  7.    assign(f,'ttt.txt');
  8.    reset(f);
  9.    s:='';
  10.      while not eof(f) do begin//пока не конец файла то...
  11.        read(f,n);//считываем символы из файла
  12.        if (n=#10) or (n=#13) then n:=' ';//Если текущий символ равен символу для перевода указателя на следующую строку
  13.                                         //или символу для перевода указателя в начало строки, то заменяем его для на пробел
  14.        s:=s+n;
  15.      end;
  16.       for i:=1 to length(s) do write(s[i]);
  17. close(f);
  18. end.

P.S.: Так как в файле символы находятся в разных строках, то для удобства интерфейса просмотра стрига, я заменил символы перевода на новую строку, пробелами

согласна с тобой, Валентин

согласна с тобой, Валентин

Валентин

зачем всё это(!?):

  1. ...
  2.   read(f,n);//считываем символы из файла
  3.   if (n=#10) or (n=#13) then n:=' ';//Если текущий символ равен символу для перевода указателя на следующую строку
  4.                                         //или символу для перевода указателя в начало строки, то заменяем его для на пробел
  5.   s:=s+n;
  6. ...

так после каждого символа будет добавляться пробел!

можно так:

  1. ...
  2.  while not(eof(f)) do begin  // пока не конец файла
  3.    read(f,c,#13,#10);// прочитали очередной символ в переменную {с}, затем перешли на новую строку
  4.    s:=s+c;// добавили этот символ в строку s
  5.   end.
  6. ...

Никита

Я написал для чего я заменил эти символы на пробелы... Можно было это вообще не делать, просто для удобства просмотра стринга

Никита

Твой код приведет к тому что в стринг запишется последовательность символов в столбик, причем каждый символ будет находиться через 2 строчки.... Посмотри условие

Валентин

А если файл будет состоять,например, из следующих символов:
h
e
l
l
o

w
o
r
l
d
)

тогда что будет ?

Никита

Вот смотри, если символы в файле имеют вид:
h #13 #10
e #13 #10
l #13 #10
l #13 #10
o #13 #10

То по твоей логике получится так:
h #13 #10
#13 #13 #10
#10 #13 #10
e #13 #10
#13 #13 #10 и т.д.