Содержание:
Работа с файлами в паскале
Виды файлов в зависимости от их описания и режимом работы
- текстовые (тип text) файлы со строками неопределенной длины;
- файлы с типом записей (двоичные или типизированные (file of) );
- файлы без типа для передачи данных блоками записей нетипизированные (file).
Описание файловых переменных:
var f1: file of char; {типизированный файл} f2: file of integer; {типизированный файл} f3: file; {нетипизированный файл} f: text; {текстовый файл}
Для связи файла в коде программы и действительного файла на внешнем носителе используется процедура ASSIGN
:
assign(myfile,'c:\text.txt'); |
где myfile
— имя переменной (объявленной ранее в области var
), ассоциированной с файлом
c:\text.txt
— путь к реальному файлу
Первый аргумент процедуры assign в паскаль — переменная, второй – путь к файлу на диске.
Текстовые файлы в паскале: процедуры работы
Текстовый файл в Паскале — это совокупность строк произвольной длины, которые разделены между собой метками конца строки, а весь файл заканчивается меткой конца файла.
Комбинация «конец строки» состоит из двух символов: перевод каретки (
ASCII-код #13
) и перевод строки (#10
). Завершается текстовый файл символом конец файла (#26
).
Возможные расширения файлов:
*.txt, *.log,
*.htm, *.html
Метод работы с текстовым файлом в Паскале предусматривает лишь последовательный доступ к каждой строке файла. Это означает, что начинать всегда возможно только с первой строки, затем проходя по каждой строке, дойти постепенно до необходимой. Т.е. можно сказать, что чтение (или запись) из файла (в файл) ведутся байт за байтом от начала к концу.
Предусмотрены два режима работы: режим для записи в файл информации и для чтения ее из файла. Одновременная запись и чтение запрещены.
Открытие файла
Допустим, мы в программе описали переменную для работы с текстовым файлом:
var f: text; |
Рассмотрим дальнейшую последовательность работы с ним, и рассмотрим процедуры, необходимые для работы с текстовым файлом в Паскале:
процедура открытия существующего файла для чтения при последовательном доступе:
Reset (f);процедура открытия создаваемого файла для записи в него информации; если файл с таким именем уже существует, то информация в нем стирается:
Rewrite (f);процедура добавления в конец:
Append (f);
- При открытии курсор устанавливается в начало файла.
Чтение из файла
Read (f, список переменных); ReadLn (f, список переменных);Отличие
ReadLn
отRead
в том, что при использовании readln после прочтения данных пропускаются все оставшиеся символы в данной строке, включая метку конца строки.
- чтение осуществляется с той позиции, где в данный момент стоит курсор;
- после чтения курсор сдвигается к первому непрочитанному символу.
EOF (end of file)
.EOL (end of line)
.close ( f ); reset ( f ); { начинаем с начала } |
Запись в текстовый файл
Write (f, список переменных); WriteLn (f, список переменных);где
f
— файловая переменная, а второй параметр – выводимые из программы и вводимые в файл данные (в виде значений переменных или просто данные)
Процедуры работы с файлом и закрытие файла
Нахождение конца файла:
Eof(f);Логическая функция, возвращающая True, если достигнут конец файла.
Нахождение конца строки:
eoln(f);Логическая функция, возвращающая True, если достигнут конец строки.
Удалить файл в Паскале
erase(переменная_файла);Переименование файла в Паскале
rename(переменная_файла,'новое имя файла');Закрытие:
Close (f); {закрытие файла}
- Процедура assign.
- Процедура reset или rewrite.
- Процедура close.
Рассмотрим пример работы с файлами в паскале:
(предварительно создать text.txt с тремя строками)
Решение:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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. |
* Из задачника М. Э. Абрамян (Text4)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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. |
Считать из файла input.txt числа (числа записаны в столбик). Затем записать их произведение в файл output.txt
Решение:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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. |
Дополните код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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. |
* Из задачника М. Э. Абрамян (Text1)
S
и текстовый файл. Добавить строку S
в конец файла.
* Из задачника М. Э. Абрамян (Text5)
S
и текстовый файл. Добавить строку S
в начало файла.
* Возможно, в программе пригодятся новые процедуры удаления и переименования файла
* Из задачника М. Э. Абрамян (Text7)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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. |
K
и текстовый файл. В данном файле вставить пустую строку перед строкой с номером K
. Если строки с таким номером нет, то оставить файл без изменений.Для решения задачи можно использовать дополнительный временный файл.
* Из задачника М. Э. Абрамян (Text9)
K
и текстовый файл. Удалить из файла строку с номером K
. Если строки с таким номером нет, то оставить файл без изменений.
* Из задачника М. Э. Абрамян (Text15)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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. |
F1
с набором нулей и единиц. Необходимо заменить все вхождения сочетаний 101
на 000
. Скорректированные записи поместить в файл F2
.
* Использовать функции для работы со строками:
— Pos()
— Delete()
— Insert()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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 элементов массива;
- записываем результат в файл.
Фрагмент решения:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | { Определяем глобальные переменные: } var A: array[1..100] of integer; f: text; N, i: integer; { Определяем функцию, считывающую числа из файла, и записывающую их в массив. Функция возвращает кол-во элементов массива: } function ReadFromFile: integer; var i: integer; begin assign(f, 'input.txt'); ...;{ открытие файла в режиме чтения } i := 0; while (...) and (...) do begin i := i + 1; readln(...,...); end; close(f); ReadFromFile := i; end; { Основная программа } Begin N := ReadFromFile ; { сортировка N элементов по возрастанию } { ... } { запись отсортированного массива в файл: } assign(..., ...); ...;{ открытие файла в режиме записи } for i:=1 to N do writeln(..., ...); close(f); end. |
* Из задачника М. Э. Абрамян (Text16)
А теперь вернемся к олимпиадному заданию по Паскалю, частично решенному на одном из предыдущих заданиях:
Решить ту же задачу, в которой сдвиг будет не на 3 позиции, а на k, причем отрицательное значение является признаком сдвига влево, положительное — вправо.
Формат входных данных (файл p.in): В первой строке записано число k, не превышающее по модулю 20. Во второй строке — текст, который необходимо зашифровать. Все символы текста латинские и прописные.
Формат выходных данных (файл p.out): Выведите зашифрованный текст.
Пример:
p.in | p.out |
---|---|
3 hello earth |
khoor hduwk |
* желательно создать файлы и записать данные в исходный файл «вручную»
* программа решена для k=3, выполните программу для любых k (не превышающих 20 по модулю)
Фрагменты кода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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 {32 - пробел} 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. |
Имя входного файла: z3.in
Имя выходного файла: z3.out
Найти сумму всех чисел от 1 до n, имеющих ровно 5 делителей.
Единица и само число входят в число его делителей.
Входные данные
В единственной строке входного файла z3.in записано одно натуральное число n(1 <= n <= 1012).
Выходные данные
В единственную строку выходного файла z3.out нужно вывести одно натуральное число — найденную сумму.
Примеры:
z3.in | z3.out |
---|---|
50 | 16 |
200 | 97 |
2015 | 722 |
* Олимпиадное задание (11 класс, 2016)
D.U
Зачем нужен c:char и name:string во втором примере?
admin
не вижу такого примера…
Владислав
Char — это переменная под символ, а String — под строку (по умолчанию 255-ти) символов. Можно было, конечно, использовать String [1], но легче же записать Char.
LEX
Моя программа:
Program z1;
var input,output: text;
str,str1:string;
i,j:integer;
Begin
assign(input,’input.txt’);
assign (output,’output.txt’);
reset(input);
rewrite(output);
while not eof(input)do Begin
while not eoln(input)do Begin
readln(input,str);
i:=length(str);writeln(str);
for j:= i downto 1 do str1:=str1+str[j];
end;
writeln(str1);
writeln(output,str1);
end;
close(input);
close(output);
end.
На входе:
Mercury 50
Venus 108
Earth 150
На выходе:
05 yrucreM801 suneV051 htraE
А надо:
05 yrucreM
801 suneV
051 htraE
Спасибо.
Денис
Не посмотрел дату, но в тоже время Вы определяете домену строки и уже потом читаете с конца к началу. Поэтому у вас все справа на лево. Так же вы производите чтение до конца строки и в тоже время читаете всю строку сразу readLN. На скидку.