Файл не открыт pascal
Для чего нам нужно уметь работать с файлами в Паскаль?
Ранее мы рассмотрели ввод и вывод данных в Паскале. Он осуществлялся вручную, с помощью клавиатуры и результат мы также смотрели сами в окне вывода. Для того чтобы быть уверенным в том, что программа написана правильно необходимо протестировать её. Для того чтобы специальные тестирующие системы автоматически проверяли решение необходимо, ввод и вывод данных осуществлять из текстовых файлов. По такой же схеме тестируются задачи на всех этапах республиканских олимпиад по информатике.
Ввод мы будем осуществлять из файла input.txt
Вывод будем производить в файл output.txt
Для организации ввода данных из файла надо:
1.Связать текстовый файл для чтения исходных данных с input:assign(input,'input.txt').
2. Открыть файл для чтения:
reset(input);
3. При работе нужно понимать и помнить отличия процедуры read, от readln. Если в файле данные записаны в одной строке, через пробел, то мы пользуемся все время процедурой read столько раз, сколько чисел нужно прочитать.
Если же строк несколько, то когда доходим до символа стоящего в конце строки, используем readln. В результате чего будет считано последнее число строки и курсор переместится на новую.
read(a); readln(a);
Например, указан следующий формат ввода:
4. Как только все переменные прочитаны необходимо закрыть файл.close(input);
Для организации вывода данных в файл надо:
1.Связать текстовый файл для записи результатов с output:assign(output,'output.txt').
2. Открыть файл для записи:
rewrite(output);
3.Для вывода используем операторы write и writeln также, как и было до сих пор.
4. Как только все переменные выведены необходимо закрыть файл.Задание 1. Перенаправление. Прочитайте число n из файла input.txt и выведите его в файл output.txt
Program z1;
var a:longint;
Begin
assign(input,'input.txt');
reset(input);
read(a);
close(input);
assign (output,'output.txt');
rewrite(output);
writeln(a);
close(output);
End.
Экспериментальный раздел
Наберите программу в среде программирования Free Pascal, запустите ее на исполнение. У Вас может появится ошибка типа:
exited with exitcode=2 (для Free Pascal), если файла input.txt нет.
Создайте в папке, где сохранена ваша программа файл input.txt и введите в него число.
В этой же папке, после удачного (без ошибок) запуска программы на исполнение должен появиться файл output.txt.
Переход между окнами входных, выходных данных и текстом программы осуществляется нажатием клавиши F6.
Задание 2. Сумма двух чисел. Даны числа А и В (0<А, B<=32000). Найти сумму А+В и вывести ее в выходной файл.
Выходные данные:
В единственную строку выходного файла вывести сумму этих чисел.
Тесты Посмотреть решение
Задание 3. Перепутал строки. Даны два числа А и В(0<=А,В<2 000 000 000). Вывести числа в обратном порядке.
Выходные данные:
В первой строке выходного файла должно быть число В.
Во второй строке выходного файла число А.
Тесты Посмотреть решение
а) его первую строку;
б) его пятую строку;
в) его первые 5 строк;
г) его строки с s1-й no s2-ю (s1 и s2 записаны в 11 строке входного файла через пробел);
д) весь файл.
Тесты Посмотреть решение
Задание 5. Сформируйте массив целых чисел (значения для него взять из файла, они записаны во 2-ой строке входного файла). В первой строке этого файла указано количество элементов массива (n<=50). Вывести в выходной файл количество отрицательных чисел массива, его наименьшее и наибольшее значения.
Во второй строке входного файла содержатся N чисел через пробел - элементы массива
Выходные данные:
Первая строка - количество отрицательных элементов массива
Тесты Посмотреть решение
assign (output,'t1.txt');
rewrite(output);
writeln(t);
close(output);
assign(input,'t.txt');
reset(input);
read(s);
close(input);
assign (output,'t2.txt');
rewrite(output);
writeln(s);
close(output);
End.
Первая строка содержит число n - количество строк
Вторая строка - n-ая строки содержат текст Выходные данные:
Для каждого выходного файла
Первая строка - n-ая строка содержат текст
Тесты Посмотреть решение
Задание 8. Даны три целых числа. Определить, имеется ли среди них хотя бы
одна пара равных между собой чисел. Выходные данные:
Выведите 'YES' если это так, и 'NO' в противном случае.
Тесты Посмотреть решение
Задание 9. Даны три числа. Определить, существует ли треугольник, сторонами которого являются эти числа, и если существует, найти его площадь. Выходные данные:
В первой строке запись "да" или "нет"
Во второй строке значение площади, если треугольник существует
Тесты Посмотреть решение
Задачи для самостоятельного решения
Для связи файла в коде программы и действительного файла на внешнем носителе используется процедура ASSIGN :
Текстовые файлы в паскале: процедуры работы
Возможные расширения файлов:
*.txt, *.log,
*.htm, *.html
Метод работы с текстовым файлом в Паскале предусматривает лишь последовательный доступ к каждой строке файла. Это означает, что начинать всегда возможно только с первой строки, затем проходя по каждой строке, дойти постепенно до необходимой. Т.е. можно сказать, что чтение (или запись) из файла (в файл) ведутся байт за байтом от начала к концу.
Предусмотрены два режима работы: режим для записи в файл информации и для чтения ее из файла. Одновременная запись и чтение запрещены.
Открытие файла
Допустим, мы в программе описали переменную для работы с текстовым файлом:
Рассмотрим дальнейшую последовательность работы с ним, и рассмотрим процедуры, необходимые для работы с текстовым файлом в Паскале:
процедура открытия существующего файла для чтения при последовательном доступе:
процедура открытия создаваемого файла для записи в него информации; если файл с таким именем уже существует, то информация в нем стирается:
процедура добавления в конец:
- При открытии курсор устанавливается в начало файла.
Чтение из файла
Read (f, список переменных); ReadLn (f, список переменных);
Отличие ReadLn от Read в том, что при использовании readln после прочтения данных пропускаются все оставшиеся символы в данной строке, включая метку конца строки.
- чтение осуществляется с той позиции, где в данный момент стоит курсор;
- после чтения курсор сдвигается к первому непрочитанному символу.
close ( f ); reset ( f );
Запись в текстовый файл
Write (f, список переменных); WriteLn (f, список переменных);
Процедуры работы с файлом и закрытие файла
Нахождение конца файла:
Логическая функция, возвращающая True, если достигнут конец файла.
Нахождение конца строки:
Логическая функция, возвращающая True, если достигнут конец строки.
Удалить файл в Паскале
Переименование файла в Паскале
rename(переменная_файла,'новое имя файла');
Закрытие:
Важно: Таким образом, работа с файлом осуществляется через три основных шага:Рассмотрим пример работы с файлами в паскале:
Пример 1: В файле text.txt записаны строки. Вывести первую и третью из них на экран.(предварительно создать text.txt с тремя строками)
var filetext: text; a,b,c:string; begin assign(filetext,'c:\text.txt'); reset(filetext); readln(filetext,a); readln(filetext,b); readln(filetext,c); close(filetext); writeln(a); writeln(c); end.
Пример 2: Дан текстовый файл. Вывести количество содержащихся в нем символов и строк (маркеры концов строк EOLN и конца файла EOF при подсчете количества символов не учитывать).* Из задачника М. Э. Абрамян (Text4)
var F: Text; N,K:integer; Name:String; C:Char; begin Assign(F,'c:\text.txt'); Reset(F); N:=0; K:=0; While not eof(F) do begin inc(N); While not eoln(f) do begin inc(K); Read(F,C); end; Readln(F); end; Close(F); Writeln(N,' ',K); end.
Пример 3:Считать из файла input.txt числа (числа записаны в столбик). Затем записать их произведение в файл output.txt
var p, x: integer; f: text; begin assign(f, 'input.txt'); reset(f); p := 1; while not eof(f) do begin readln(f, x); p := p * x; end; close(f); assign(f, 'output.txt'); rewrite(f); writeln(f, 'Произведение чисел ', p); close(f); end.
var filetext: text; a:string; i:integer; begin assign(filetext,'c:\text.txt'); rewrite(filetext); for i:=1 to 10 do . reset(filetext); for i:=1 to 10 do begin . . end; close(filetext); end.
pascal file text2. Даны целые положительные числа N и K. Создать текстовый файл и записать в него N строк, каждая из которых состоит из K символов «*» (звездочка).* Из задачника М. Э. Абрамян (Text1)
pascal file text3. Дана строка S и текстовый файл. Добавить строку S в конец файла.* Из задачника М. Э. Абрамян (Text5)
Пример 4: Дана строка S и текстовый файл. Добавить строку S в начало файла.* Из задачника М. Э. Абрамян (Text7)
var F_in,F_out: Text; Name,S: String; begin Write('S: '); Readln(S); Assign(F_in,'c:\text.txt'); Reset(F_in); Assign(F_out,'c:\text1.txt'); Rewrite(F_out); Writeln(F_out,S); While not eof(F_in) do begin Readln(F_in,S); Writeln(F_out,S); end; Close(F_in); Close(F_out); Erase(F_in); Rename(F_out,'c:\text.txt'); end.
pascal file text4. Дано целое число K и текстовый файл. В данном файле вставить пустую строку перед строкой с номером K . Если строки с таким номером нет, то оставить файл без изменений.Для решения задачи можно использовать дополнительный временный файл.
* Из задачника М. Э. Абрамян (Text9)
Пример 5: Дано целое число K и текстовый файл. Удалить из файла строку с номером K . Если строки с таким номером нет, то оставить файл без изменений.* Из задачника М. Э. Абрамян (Text15)
var F_in,F_out: Text; Name,line: string; K,i:integer; begin Write('K: '); Readln(K); Assign(F_in,'c:\text.txt'); Assign(F_out,'c:\text1.txt'); Reset(F_in); Rewrite(F_out); i:=0; While not eof(F_in) do begin Readln(F_in,line); inc(i); if i<>K then Writeln(F_out,line); end; Close(F_in); Close(F_out); Erase(F_in); Rename(F_out,'c:\text.txt'); end.
Пример 6: Дан текстовый файл F1 с набором нулей и единиц. Необходимо заменить все вхождения сочетаний 101 на 000 . Скорректированные записи поместить в файл F2 .var f1,f2: text; pole:string; pz:integer; begin assign(f1,'1.txt'); assign(f2,'2.txt'); reset(f1); rewrite(f2); while not eof(f1) do begin readln(f1, pole); while pos('101',pole)<>0 do begin pz:=pos('101',pole); delete(pole,pz,3); insert('000',pole,pz); end; writeln(f2,pole) end; close(f1); close(f2); end.
Работа с данными из файла как с массивом
- для сортировки необходим массив, для того чтобы одновременно работать со всеми числами;
- неизвестно общее количество чисел.
- объявляем массив для 100 элементов;
- открываем файл на чтение, просчитываем количество чисел, заполняя массив, сохраняем количество в N;
- сортируем N элементов массива;
- записываем результат в файл.
* Из задачника М. Э. Абрамян (Text16)
А теперь вернемся к олимпиадному заданию по Паскалю, частично решенному на одном из предыдущих заданиях:
p.in | p.out |
---|---|
3 hello earth | khoor hduwk |
var a:char; i,n,k:byte; s,s1:string; f_in,f_out:text; begin Assign(F_in,'z:\p.in'); Assign(F_out,'z:\p.out'); Reset(F_in); Rewrite(F_out); s1:=''; readln(f_in,k); readln(f_in,s); for i:=1 to length(s) do begin n:=ord(s[i]); if n<>32 then n:=n+3; if . then . ; if . then . ; if . then . ; a:=chr(. ); s1:=. ; end; writeln(s1); writeln(f_out,s1); close(f_in); close(f_out) end.
var a:char; i,n,k:byte; s,s1:string; f_in,f_out:text; begin Assign(F_in,'z:\p.in'); Assign(F_out,'z:\p.out'); Reset(F_in); Rewrite(F_out); s1:=''; readln(f_in,k); readln(f_in,s); for i:=1 to length(s) do begin n:=ord(. ); if n<>32 then n:=n+3; if n=123 then n:=97; if n=124 then n:=98; if n=125 then n:=99; a:=chr(n); s1:=s1+a; end; writeln(s1); writeln(f_out,s1); close(f_in); close(f_out) end.
полное решение var s, s1: string; i, j, a, n, k, b: integer; begin n := 97; s1 := ''; readln(s); readln(k); for i := 1 to length(s) do begin if s[i] <> ' ' then begin a := ord(s[i]); if a > 122 - k then for j :=123 - k to 122 do begin b:=122-j; if a = j then begin a := n+k-b-1; inc(n); end; end else a := a + k; s1 := s1 + chr(a) end else s1 := s1 + ' ' end; writeln(s1)end. --> pascal file text7. Пять делителей.Имя входного файла: z3.in
Имя выходного файла: z3.out
Каждый программист должен знать, как работать с файлами. Файлы используются для сохранения данных, т. е. в качестве хранилища данных, таким образом, что они могут быть получены в любой момент, без их воссоздания. Файлы можно использовать для сохранения пользовательских настроек, журналов ошибок, измерение или вычисление результатов, и многое другое. В данном разделе описываются основы использования файлов.
Процедурный стиль
Это довольно старый стиль, использующейся ещё во времена, когда Pascal не был объектно-ориентированным языком. Суть его в том, что задается тип файла, определяющий, какие будут храниться в нем данные. Для этого, используется конструкция вида: file of <тип данных>, где <тип данных> - название типа, который хранит в себе файл. Помимо стандартных типов (integer, extended, char и т.д.), существует особый тип - TextFile. Он определят, что каждая строка заканчивается специальным(ми) символом(ами) конца строки (См. LineEnding). Эти файлы могут быть открыты и отредактированы внутри среды Lazarus или в любом другом текстовом редакторе.
Ниже представлены примеры создания собственных типов файлов:
Обработка ошибок ввода/вывода
Параметр компилятора обработки ошибок ввода/вывода указывает, как должна вести себя программа при возникновении ошибки в процессе работы с файлами: вызвать исключение или хранить результат операции ввода/вывода в специальной переменной IOResult.
Это задаётся с помощью специальной директивы компилятора:
В случаи подавления ошибок ввода-вывода () результат операции с файлом будет храниться в переменной IOResult типа cardinal (числовой тип). Каждое число, хранимое в IOResult определяет тип возникшей ошибки(подробнее: [1]).
Процедуры работы с файлами
Эти процедуры и функции находятся в модуле system. Для более подробной информации смотрите документацию FPC:
- AssignFile (не допускайте использование процедуры Assign) - Связывает переменную с файлом
- Append - Открывает существующий файл для записи данных в конец и их редактирования
- BlockRead - Чтение данных из не типизированного файла в память
- BlockWrite - Запись данных из памяти в не типизированный файл
- CloseFile (не допускайте использование процедуры Close) - Закрыть открытый файл
- EOF - Проверка наличия конца файла
- Erase - Стереть файл с диска
- FilePos - Получить позицию в файле
- FileSize - Получить размер файла
- Flush - Записать файловый буфер на диск
- IOResult - Возвращает результат последней операции ввода\вывода
- Read - Считать из текстового файла
- ReadLn - Считать из текстового файла и перейти к следующей строке
- Reset - Открыть файл для чтения
- Rewrite - Создать и открыть файл для записи
- Seek - Изменить позицию в файле
- SeekEOF - Переместить позицию в файле в его конец
- SeekEOLn - Переместить позицию в файле в конец строки
- Truncate - Удалить все данные, после текущей позиции
- Write - Записать переменную в файл
- WriteLn - Записать переменную в текстовый файл и перейти к новой строке
Пример
Пример работы с текстовым файлом (тип TextFile):
Теперь откройте файл в любом текстовом редакторе и вы увидите, что пример текста, записан в нем! Вы можете проверить работу обработки ошибок, установив атрибут файла "только для чтения" и снова запустив программу.
Обратите внимание, что в примере используется блок try/except. Данный способ позволяет выполнять несколько операций с файлами и использовать обработку исключений. Вы также можете использовать режим , но тогда вам придется проверять переменную IOResult после каждой операции с файлами для контроля ошибок.
Ниже приведен пример записи текста в конец файла:
Чтение текстового файла:
Объектный стиль
В дополнение к старому методу обработки файлов, упомянутому выше процедурному стилю, существует новая система, которая использует концепции потоков (данных) на более высоком уровне абстракции. Это означает, что данные могут считываться или записываться в любом месте (диск, память, аппаратные порты и т. д.) через один универсальный интерфейс.
Кроме того, большинство классов обработки строк, могут иметь возможность загружать/сохранять содержимое из/в файл. Эти методы обычно называются SaveToFile и LoadFromFile.
Двоичные файлы
Для прямого доступа к файлам, так же удобно использовать класс TFileStream. Этот класс представляет собой инкапсуляцию системных процедур FileOpen, FileCreate, FileRead, FileWrite, FileSeek и FileClose, расположенных в модуле SysUtils.
В приведенном ниже примере обратите внимание, что обработка действий с файлом, расположена внутри блока try..except. Поэтому обработка ошибок происходит так же, как в случаи использования процедур работы с файлами в классическом Pascal.
Вы так же можете загрузить весь файл в память, если его размер существенно меньше, чем имеющийся системной памяти. Если файл превышает размер системной памяти, то ваша операционная система начнет использовать файл подкачки, снижая скорость работы с файлом.
Для работы с файлами большого объёма, рекомендуется использовать буфер, например в 4096 байт.
Копирование файла
Теперь,зная методы работы с файлами, мы можем реализовать простую функцию копирования файла, скажем FileCopy.(такой функции нет в FreePascal, хотя Lazarus её имеет copyfile):
Обработка текстовых файлов (TStringList)
Для текстовых файлов можно использовать класс TStringList, чтобы загрузить весь файл в память и иметь легкий доступ к его строкам. Вы также можете записать StringList обратно в файл:
Демо: сохранить одну строку в файл
Для того, чтобы сохранить одну строку в файл, вы можете воспользоваться процедурой, описанной ниже.
- Out of memory (выход за границы памяти) Компилятору не хватает памяти. Имеется ряд возможных решений этой проблемы:
- Если в опции COMPILE/DESTINATION установлено значение MEMORY, замените эту опцию на DISK.
- Если в опции OPTIONS/COMPILER/LINK установлено значение MEMORY, замените эту опцию на DISK.
- Если Вы используете постоянно помещенные в память (резидентные) обслуживающие программы, такие как WINDOWS, SIDEKICK, NORTON
удалите их из памяти. - Если Вы используете интегрированную среду TURBO.EXE, то попробуйте воспользоваться компилятором ТРС.ЕХЕ, он занимает меньше памяти.
- Если ни одна из рекомендаций не помогает, то, возможно, Ваша программа просто слишком велика, чтобы компилировать ее в таком объеме памяти. В этом случае Вы должны разбить её на два или более модулей.
- Ваш исходный файл закончился перед последним END основного раздела< операторов. Вероятно, в Вашей программе неодинаковое количество операторов BEGIN и END.
- Включаемый файл заканчивается в середине раздела операторов. Каждый раздел операторов должен целиком помещаться в одном файле.
- Вы не закончили комментарий.
- Несовместимые типы переменной и выражения в операторе присваивания.
- Несовместимые типы фактического и формального параметров в обращении к процедуре или функции.
- Тип выражения несовместим с типом индекса при индексировании массива.
- Несовместимые типы операндов в выражении.
- Данный идентификатор получил тип PUBLIC, с помощью соответствующей директивы языка ассемблер, но не соответствует описанию EXTERNAL в программе или программном модуле Паскаля.
- Две или более директивы PUBLIC языка ассемблер определяют один и тот же идентификатор.
- Файлы .obj определяют символы PUBLIC, не находящиеся в сегменте CODE.
- Программа на ассемблере ссылается с помощью директивы ETRN на идентификатор, который не описан в программе на Паскале и не был описан в интерфейсных секциях используемых программных модулей.
- Ассемблерная программа ссылается на идентификатор, обозначающий абсолютную переменную (т.е. определённую словом ABSOLUTE).
- Ассемблерная программа ссылается на идентификатор процедуры или функции типа INLINE.
- Были описаны процедура или функция в интерфейсной секции программного модуля, но их определение отсутствует в секции реализации.
- Процедуры или функции были описаны с помощью опережающего описания, но их определение не найдено.
- Попытка разместить в памяти, занимаемой некоторой переменной, значение выражения другого типа в случае, когда размер размещаемого значения не равен размеру переменной.
- Вы пытаетесь осуществить преобразование типа выражения, когда разрешается только ссылка на переменную, процедуру или функцию.
- Процедуры READ и READLN могут считывать переменные символьного, целого, действительного и строкового типа.
- Процедуры WRITE и WRITELN могут выводить переменные символьного, целого, действительного, логического и строкового типа.
- Вы пытаетесь указать индекс массива, выходящий за его границы.
- Вы пытаетесь присвоить переменной значение, выходящее за границы, допустимые для типа этой переменной.
- Вы пытаетесь передать в качестве фактического параметра процедуре или функции константу, выходящую за границы, допустимые для типа соответствующего формального параметра.
- Общий размер глобальных переменных, описанных в программе или программном модуле, не может превышать 64 Кбайт.
- Размер локальных переменных, описанных в программе или функции, не может превышать 64 Кбайт.
- Вы пытаетесь индексировать переменную, которая не является массивом.
- Вы пытаетесь указать поля в переменной, которая не является записью.
- Вы пытаетесь использовать в качестве указателя переменную, которая не является указателем.
- Заголовок процедуры или функции, указанный в интерфейсной секции, не соответствует заголовку в исполняемой части.
- Заголовок процедуры или функции, указанный с помощью опережающего описания (FORWARD), не соответствует заголовку найденной далее одноименной процедуры или функции.
Ошибки ввода-вывода вызывают завершение выполнения программы в случае, если оператор ввода-вывода был скомпилирован в режиме . В режиме продолжается выполнение программы, а ошибка возвращается функцией IORESULT. Коды ошибок 1-99 соответствуют кодам ошибок ДОС. 100-149 - ошибкам ввода вывода, 150-199 - критическим ошибкам, а 200-255 - фатальным ошибкам.
Если один из операторов компилируется с директивой , то ошибка ввода-вывода приводит к прекращению выполнения программы. В состоянии программа продолжает выполняться, а ошибка возвращается функцией IORESULT.
- Индексное выражение массива находилось вне допустимого диапазона.
- Была осуществлена попытка присвоить переменной значение, находящееся вне диапазона переменной.
- Была осуществлена попытка передать значение, находящееся вне допустимого диапазона, в качестве параметра процедуре или функции.
- Аргумент функции TRUNC или ROUND не может быть преобразован в целое число, находящееся внутри диапазона типа LONGINT (от -2147483648 до +2147483647).
- Отрицательный аргумент функции SQRT (извлечение квадратного корня).
- Аргумент функции LN (логарифм) равен нулю или имеет отрицательное значение.
- Произошло переполнение стека сопроцессора.
Читайте также: