Каждый
открытый файл, как уже отмечалось, имеет
скрытый указатель на
текущую позицию в нем. При открытии
файла этот указатель устанавливается
на начало данных, и все операции в файле
будут производиться с данными,
начинающимися в этой позиции.
При
каждом выполнении функции чтения или
записи указатель смещается на количество
прочитанных или записанных байт, т.е.
устанавливается после прочитанного
или записанного блока данных в файле –
это последовательный
доступ к данным.
В языке
Си/С++ можно установить указатель на
некоторую заданную позицию в файле. Для
этого используют стандартную функцию
fseek,
которая позволяет выполнить чтение или
запись данных в произвольном порядке.
Декларация функции
позиционирования следующая:
int
fseek(FILE
*f,
long
size,
int
code);
Значение
параметра size
задает количество байт, на которое
необходимо сместить указатель в файле
f,
в направлении параметра code,
который может принимать
следующие значения:
– смещение от |
0 |
(SEEK_SET); |
– смещение от |
1 |
(SEEK_CUR); |
– смещение от |
2 |
(SEEK_END). |
Таким образом,
смещение может быть как
положительным, так и отрицательным, но
нельзя выходить за пределы файла.
В случае успеха
функция возвращает нулевое значение,
а в случае ошибки (например, попытка
выхода за пределы файла) – единицу.
Доступ к файлу с
использованием функции позиционирования
(fseek) называютпроизвольным доступом.
Иногда нужно
определить текущее положение в файле.
Для этого используют функцию со следующей
декларацией:
long ftell(FILE*f);
которая
возвращает значение указателя на текущую
позицию в файле или –1 в случае ошибки.
14.5. Дополнительные файловые функции
В заключение
рассмотрим наиболее распространенные
функции, с помощью которых можно
организовать работу с файлами:
intfileno (FILE*f) – определяет
и возвращает значение дескриптора (fd)
файлаf, т.е. число, определяющее
номер файла;
longfilelength (intfd) – возвращает
длину файла, имеющего дескрипторfd, в байтах;
intchsize (intfd,longpos) – выполняет
изменение размера файла, имеющего номерfd, признак конца файла устанавливается
после байта с номеромpos;
intfeof (FILE*f) – возвращает
ненулевое значение при правильной
записи признака конца файла;
intfgetpos (FILE*f,long*pos) – определяет
значение текущей позицииposфайлаf.
Пример
программы работы с файлом структур
Создать
программу, в которой реализованы
создание, добавление и просмотр файла,
содержащего информацию о фамилии и
среднем балле студентов. Процесс
добавления информации заканчивается
при нажатии точки.
#include
<stdio.h>
#include
<stdlib.h>
struct
Sved {
char
Fam[30];
double
S_Bal;
}
zap,zapt;
char
Spis[]=”c:\work\Sp.dat”;
FILE
*F_zap;
FILE*
Open_file(char*, char*);
void
main (void)
{
int
i, j, kodR, size = sizeof(Sved), kod_read;
while(1)
{
puts(“Создать
– 1n Добавить– 3nПросмотреть– 2nВыход
– 0”);
scanf(“%d”,&kodR);
switch(kodR)
{
case
1: case 3:
if(kodR==1)
F_zap = Open_file (Spis,”w+”);
else
F_zap = Open_file (Spis,”a+”);
while(2)
{
puts(“n
Fam (. – end) “);
scanf(“%s”,zap.Fam);
if((zap.Fam[0])==’.’)
break;
puts(“n
Ball: “);
scanf(“%lf”,&zap.S_Bal);
fwrite(&zap,size,1,F_zap);
}
fclose(F_zap);
break;
case 2: F_zap = Open_file (Spis,”r+”); int nom=1;
while(2)
{
if(!fread(&zap,size,
1, F_zap)) break;
printf(”
%2d: %20s %5.2lfn”,
nom++,
zap.Fam, zap.S_Bal);
}
fclose(F_zap);
break;
case
0: return; // exit(0);
}
// Закрывает switch()
} //
Закрывает while()
}
//
Функция обработки ошибочной ситуации
при открытии файла
FILE*
Open_file(char *file, char *kod)
{
FILE
*f;
if(!(f
= fopen(file, kod))) {
puts(“Open
File Error!”);
exit(1);
}
return
f;
}
Соседние файлы в папке птс1кр
- #
- #
- #
- #
- #
- #
- #
#python #python-3.x #csv
#python #python-3.x #csv
Вопрос:
У меня есть этот файл csv.
JFK,John F Kennedy International,5326,5486
ORY,Paris-Orly,629,379
MAD,Adolfo Suarez Madrid-Barajas,1428,1151
AMS,Amsterdam Schiphol,526,489
CAI,Cairo International,3779,3584
Если есть способ, как можно найти положение элемента, такого как JFK
и, и распечатать его, вызвав postition, как мне это сделать?. Если это не ясно: как мне закодировать оператор печати, который печатает JFK
или John F Kennedy International
. Я не настолько хорош в python, поэтому извините, если это было трудно понять.
Ответ №1:
Вы можете создать словарь первого элемента, сопоставляющего второму элементу, следующим образом:
import csv
with open(fn) as f: # where fn is the file name
di={row[0]:row[1] for row in csv.reader(f)}
Тогда тривиально получить каждое значение из кода airport:
>>> di
{'JFK': 'John F Kennedy International', 'ORY': 'Paris-Orly', 'MAD': 'Adolfo Suarez Madrid-Barajas', 'AMS': 'Amsterdam Schiphol', 'CAI': 'Cairo International'}
>>> di['JFK']
'John F Kennedy International'
Ответ №2:
попробуйте это:
import pandas
df = pandas.read_csv("<path_to_csv_file>")
value = df.loc[df["<column_name>"] == "JFK"]
print(value)
Надеюсь, я помог!
Ответ №3:
С помощью модуля python CSV вы можете читать весь файл CSV строка за строкой:
import csv
with open('your.csv', mode ='r')as file:
csvFile = csv.reader(file)
x = list(csvFile)
print(x)
Результат
[['JFK', 'John F Kennedy International', '5326', '5486'], ['ORY', 'Paris-Orly', '629', '379'], ['MAD', 'Adolfo Suarez Madrid-Barajas', '1428', '1151'], ['AMS', 'Amsterdam Schiphol', '526', '489'], ['CAI', 'Cairo International', '3779', '3584']]
Из напечатанного результата вы заметите, что каждая строка вашего csv представлена как подсписок результата. Итак, если вы печатаете первый элемент первого подсписка, у вас должно быть JFK
print(x[0][0])
Результат
JFK
How can I get the current line position of the file pointer?
codaddict
443k81 gold badges491 silver badges528 bronze badges
asked Mar 28, 2010 at 15:40
There is no function that gives you current line. But you can use ftell function to get the offset in terms of number of char from the start of the file.
answered Mar 28, 2010 at 15:42
codaddictcodaddict
443k81 gold badges491 silver badges528 bronze badges
3
There is no function to get the current line; you’ll have to keep track of it yourself. Something like this:
FILE *file;
int c, line;
file = fopen("myfile.txt", "rt");
line = 0; /* 1 if you want to call the first line number 1 */
while ((c = fgetc(file)) != EOF) {
if (c == 'n')
++line;
/*
... do stuff ...
*/
}
answered Mar 28, 2010 at 15:49
ThomasThomas
173k48 gold badges353 silver badges475 bronze badges
You need to use ftell to give you the position within the file.
If you want the current line, you’ll have to count the number of line terminator sequences between the start of the file and the position. The best way to do that is to probably start at the beginnning of the file and simmply read forward until you get to the position, counting the line terminator sequences as you go.
If you want the current line position (I assume you mean which character of the current line you’re at), you’ll have to count the number of characters between the line terminator sequence immediately preceding the position, and the position itself.
The best way to do that (since reading backwards is not as convenient) is to use fseek to back up a chunk at a time from the position, read the chunk into a buffer, then find the last line terminator sequence in the chunk, calculating the difference between that point and the position.
answered Mar 28, 2010 at 15:49
paxdiablopaxdiablo
847k233 gold badges1568 silver badges1942 bronze badges
1
Линейный односвязный список. Общие сведения. Базовые операции над списком
Содержание
- 1. Понятие об односвязном списке. Особенности кодировки. Базовые операции над списком
- 2. Общий вид списка. Структура, описывающая один элемент списка
- 3. Формирование списка
- 3.1. Создать пустой список
- 3.2. Добавление элемента в конец списка
- 3.2.1. Добавление нового элемента в конец пустого списка
- 3.2.2. Добавление элемента в конец существующего списка
- 4. Вставка элемента в заданную позицию списка
- 4.1. Список не пуст. Вставка элемента в первую позицию списка
- 4.2. Список не пуст. Вставка элемента в середину списка
- 5. Удаление элемента из списка в заданной позиции
- 5.1. Список не пуст. Удаление первого элемента из списка
- 5.2. Список не пуст. Удаление не первого элемента из списка
- Связанные темы
Поиск на других ресурсах:
1. Понятие об односвязном списке. Особенности кодировки. Базовые операции над списком
Односвязный список является динамической структурой данных, реализующей формирование и обработку набора элементов. Элементы односвязного списка могут быть отсортированы или не отсортированы.
Односвязный список может сохраняться:
- в оперативной памяти;
- в файле.
В односвязном списке выделяют отдельный элемент (Element), который называется узел (Node).
Каждый элемент (узел) односвязного списка состоит из двух частей:
- данные. Это может быть переменная любого примитивного типа (int, double, char, …), объект класса или сложная структура. Данные могут состоять из нескольких полей (переменных);
- адрес или позиция следующего элемента. Если односвязный список хранится в оперативной памяти, то это указатель (адрес) на такой же элемент (узел). Если односвязный список хранится в файле, то это позиция следующего элемента в файле.
Реализовать узел можно с помощью класса или структуры. Также можно создавать односвязный список на основе шаблонного класса, оперирующего некоторым обобщенным типом T.
Совокупность элементов (узлов), в которых указатель предыдущего элемента указывает следующий элемент, образует односвязный список.
Для списка можно выделить следующие основные операции:
- формирование списка;
- добавление элемента в конец списка;
- вставка элемента в заданную позицию списка;
- удаление элемента из списка из заданной позиции;
- очистка списка;
- замена элемента в списке;
- поиск элемента в списке по индексу или некоторому критерию.
При желании перечень операций можно расширить, добавив собственные идеи (например, вставка группы элементов в список, сортировка элементов в списке, создание отсортированного списка и т.п.).
⇑
2. Общий вид списка. Структура, описывающая один элемент списка
Общий вид линейного односвязного списка изображен на рисунке 1.
Рисунок 1. Общий вид списка
На рисунке 2 изображена структура Element, используемая как базовый элемент линейного односвязного списка. В каждом элементе хранятся данные некоторого типа T.
Рисунок 2. Структура Element, описывающая один элемент списка с программным кодом на языке C++
⇑
3. Формирование списка
3.1. Создать пустой список
Создание списка включает следующие этапы.
1. Объявление указателей на начало и конец списка.
2. Установка нулевых значений указателям.
3. Установка количества элементов в значение 0.
Рисунок 3. Формирование списка: 1) — объявление указателей; 2) — установка нулевых значений
⇑
3.2. Добавление элемента в конец списка
При добавлении элемента в конец списка рассматривают 2 возможные ситуации:
- добавление элемента в пустой список;
- добавление элемента в непустой список (список, в котором есть элементы).
⇑
3.2.1. Добавление нового элемента в конец пустого списка
При добавлении элемента в конец пустого списка выделяют следующие операции (рисунок 4):
1. Создать новый элемент. Здесь нужно выделить память для нового элемента и заполнить ее некоторыми данными (_data). Для этого объявляется указатель (например, elem):
Element<T>* elem = new Element<T>; elem->data = _data;
2. Установить указатель next в нулевое значение
elem->next = nullptr;
3. Установить указатели begin и end равными значению указателя elem.
begin = end = elem;
4. Увеличить количество элементов в списке на 1
count++;
Рисунок 4. Добавление элемента в конец пустого списка: 1 – создание элемента; 2 – установка указателя next; 3 – установка указателей begin и end
⇑
3.2.2. Добавление элемента в конец существующего списка
Если список уже существует, то последовательность шагов добавляющих элемент в список следующая (рисунок 5):
1. Создать новый элемент и заполнить его данными (рисунок 5). Заполняются поля data и next. Создание элемента осуществляется таким же образом как в случае с пустым списком:
Element<T>* elem = new Element<T>; elem->data = _data; elem->next = nullptr;
2. Установить указатель next элемента, на который указывает указатель end, в значение адреса элемента elem (рисунок 6)
end->next = elem;
3. Установить указатель end равным значению указателя elem
end = elem;
4. Увеличить количество элементов в списке на 1
count++;
Вышеприведенные шаги более красноречиво отображаются на рисунках 5, 6, 7.
Рисунок 5. Создание элемента и заполнение его данными
Рисунок 6. Изменение указателя next элемента end
Рисунок 7. Установка указателя end на последний элемент списка
⇑
4. Вставка элемента в заданную позицию списка
При вставке элемента в заданную позицию списка рассматриваются 2 варианта:
- список пуст (нет элементов);
- список имеет хотя бы один элемент.
Если список пуст, то вставка заменяется добавлением первого элемента, как описано в пункте 3.2.1.
Если в списке есть элементы, то здесь рассматриваются 3 варианта:
- вставка элемента в первую позицию списка;
- вставка элемента внутри списка;
- вставка элемента за последним элементом списка. Если происходит вставка за последним элементом списка, то это есть добавление элемента в конец списка как описано в пункте 3.2.2.
⇑
4.1. Список не пуст. Вставка элемента в первую позицию списка
Если происходит вставка элемента в первую позицию списка, то последовательность операций следующая:
1. Создайть новый элемент (рисунок 8). Выделить память под новый элемент. Заполнить элемент данными.
// Выделение памяти под новую ячейку Element<T>* elem = new Element<T>; elem->data = _data;
2. Установить указатель next элемента на начало списка (рисунок 9).
elem->next = begin;
3. Установить начало списка на новую ячейку (рисунок 10).
begin = elem;
Все вышеперечисленные шаги графически изображены на рисунках 8, 9, 10.
Рисунок 8. Создание нового элемента. Заполнение полей элемента значениями
Рисунок 9. Вставка элемента в начало списка. Установка поля next равного адресу первого элемента списка
Рисунок 10. Присваивание указателю начала списка адреса новосозданного элемента
⇑
4.2. Список не пуст. Вставка элемента в середину списка
Если элемент вставляется перед второй, третьей и т.д. а также последней позицией списка, то выполняются нижеследующие шаги.
1. Создать элемент. Заполнить поле данных элемента
Element<T>* elem = new Element<T>; elem->data = _data;
2. Определить позицию элемента, который следует перед позицией вставки элемента. Получить указатель на эту позицию.
Element<T>* elemPrev = Move(index - 1);
здесь Move() – метод, возвращающий позицию элемента, находящегося перед позицией вставки index.
3. Установить указатель next элемента elem, который вставляется
elem->next = elemPrev->next;
4. Установить указатель next предыдущего элемента elemPrev так, чтобы он указывал на вставляемый элемент elem
elemPrev->next = elem;
Предыдущие 4 шага изображены на рисунках 11, 12, 13, 14.
Рисунок 11. Создание элемента. Заполнение элемента данными
Рисунок 12. Вставка элемента в список. Поиск элемента, который следует перед позицией вставки
Рисунок 13. Вставка элемента в список. Установка указателя next вставляемого элемента
Рисунок 14. Вставка элемента в список. Установка указателя next элемента, следующего перед позицией вставки
⇑
5. Удаление элемента из списка в заданной позиции
Чтобы удалить элемент из списка, сначала производится проверка, пуст ли список. Если список не пуст (список содержит хотя бы один элемент), то производится удаление элемента.
При удалении элемента из списка рассматриваются 2 возможные ситуации:
- удаляется первый элемент из списка;
- удаляется не первый элемент из списка (второй, третий и т.д.).
⇑
5.1. Список не пуст. Удаление первого элемента из списка
Если удаляется первый элемент в списке, то последовательность шагов удаления следующая.
1. Получить адрес первого элемента (рисунок 15)
Element<T>* delElem = begin;
2. Переместить указатель на начало списка begin на следующий элемент
begin = begin->next;
3. Освободить память, выделенную для элемента delElem
delete delElem;
На рисунках 15, 16, 17 изображен весь процесс удаления первого элемента из списка.
Рисунок 15. Удаление первого элемента из списка. Шаг 1. Создать указатель на первый элемент
Рисунок 16. Удаление элемента. Шаг 2. Перемещение указателя начала списка на следующий элемент
Рисунок 17. Удаление элемента. Шаг 3. Освободить память, выделенную под элемент
⇑
5.2. Список не пуст. Удаление не первого элемента из списка
Если в непустом списке удаляется не первый элемент (второй, третий и т.д., последний), то последовательность шагов следующая.
1. Переместить указатель на позицию, следующую перед удаляемым элементом. Получить элемент, предшествующий удаляемому элементу
Element<T>* elemPrev = Move(index - 1);
здесь Move() – метод, возвращающий элемент по указанной позиции.
2. Запомнить удаляемый элемент
Element<T>* elemDel = elemPrev->next;
3. Сместить указатель next предыдущего элемента elemPrev в обход удаляемого элемента elemDel
elemPrev->next = elemDel->next;
4. Удалить элемент elemDel (освободить память, выделенную для элемента).
delete elemDel;
На рисунках 18, 19, 20, 21 схематически рассмотрены вышеприведенные шаги.
Рисунок 18. Удаление элемента всередине списка. Переход на элемент, следующий перед предыдущим
Рисунок 19. Удаление элемента. Получить удаляемый элемент
Рисунок 20. Удаление элемента из списка. Смещение указателя next предыдущего элемента в обход удаляемого элемента
Рисунок 21. Удаление элемента из списка. Особождение памяти, занимаемой элементом
⇑
Связанные темы
- Пример реализации линейного односвязного списка для обобщенного типа T
- Линейный двухсвязный список. Общие сведения. Базовые операции со списком
- Линейный двухсвязный список. Пример шаблонного класса
- Разработка шаблонного класса, реализующего стек в виде односвязного списка
⇑
§12. Файлы.
Мы многое узнали и многому научились. Сейчас возникает естественная потребность в обработке больших объёмов информации и в том, что бы сохранять результаты работы программы. Если вы хоть немного владеете, как пользователь, компьютером, то вы, конечно, скажете, что это можно реализовать с помощью файлов.
Под словом файл мы будем понимать совокупность данных расположенных на жёстком диске компьютера. Сейчас мы не будем вдаваться в подробности, как устроена файловая система, и как осуществляется хранение информации на жёстком диске. Всё это скрыто от программиста Pascal-ем и операционной системой.
Для того, что бы работать с файлом в Pascal, необходимо создать переменную типа файл или другими словами файловую переменную. Все операции с файлами осуществляются через эту переменную. Не надо думать, что эта переменная и есть файл. Эта переменная является указателем на реальный файл. Когда вы будете вызывать какую-либо процедуру или функцию работы с файлом, вы будете в качестве параметра использовать файловую переменную, которая будет указывать процедуре или функции с каким именно файлом необходимо работать.
В Pascal существует три вида файлов это: типизированные, текстовые файлы и нетипизированные. Перед тем, как начать их изучать поговорим об именах файлов.
Имена файлов.
Имя файла – это строка, состоящая из любой последовательности символов. В именах файлов разрешено использовать не все символы. К разрешённым относятся все буквы, цифры и ряд символов: «! @ # $ % ^ & ( ) ‘ ` ~ – _ . ,», а также можно использовать пробел, в том случае если есть другие символы.
Обычно в имени файла содержится расширение, которое находится в конце имени и отделяется от него точкой. На практике расширение необходимо для того, что бы было понятно, что это за файл. Это может быть исполняемый файл т.е. программа (расширение .exe), или это файл какой-либо программы, например документ Microsoft Word (расширение .docx). Когда будете придумывать расширение, постарайтесь что бы оно что-либо обозначало.
Так же имя файла может содержать в себе полный путь, т.е. местоположение файла. Полный путь начинается с имени диска или устройства, на котором находится файл. Имена дисков или устройств состоят из одной буквы латинского алфавита. Как правило, буквы «A» и «B» зарезервированы под дисководы, которые на данный момент уже устарели и практически не используются. Далее идёт диск «C» – это обычно раздел жёсткого диска, на котором, как правило, установлена операционная система. Если жесткий диск имеет более одного раздела, то эти разделы будут называться следующими по алфавиту символами. Потом даётся имя CD-DVD-рому. Затем имя может получить флешка.
После буквы устройства, на котором находится файл, ставиться двоеточие и косая черта «». Затем идут названия каталогов, в которых находится файл. Названия каталогов разделяются косой чертой «». Например, имя файла может быть следующим:
«c:WindowsMediachord.wav».
Типизированные файлы.
В типизированном файле может находиться последовательность данных какого либо одного типа. Отсюда и название. Типы, которые могут содержаться в типизированном файле могут быть любые, кроме строк переменной длины.
Для создания файловой переменной, которая будет указывать на типизированный файл, используется словосочетание file of, после которого указывается тип данных, которые будут содержаться в файле, например:
var f:file of integer;
Так же можно, в начале, создать свой тип, а затем создать переменную этого типа:
Type Tf = file of integer;
var f:Tf;
Далее необходимо связать файловую переменную с файлом, на который она будет указывать. Делается это с помощью процедуры assign:
assign(f,‘c:111111.int’);
В скобках первым параметром идёт файловая переменная, вторым – строка, которая содержит в себе имя файла. С помощью процедуры Assign мы связали файловую переменную с реальным файлом. Причём самого файла на момент вызова процедуры assign может ещё и не существовать. Просто процедура assign связывает файловую переменную и имя файла, а так же путь к нему.
Далее для того, что бы создать реальный файл необходимо вызвать процедуру rewrite(f). При этом будет создан новый пустой файл, причём если файл с таким именем уже существовал, то он будет удалён. Т.е. процедура rewrite создаёт новый файл, на который указывает файловая переменная:
rewrite(f);
После того, как был создан новый файл, в него можно записывать данные с помощью уже знакомой нам процедуры write. Причём первым параметром должна находиться файловая переменная, а затем через запятую перечисляются переменные или константы, которые необходимо записать в файл. Причём эти константы и переменные должны быть того типа, который указан при объявлении файловой переменной:
write(f,3,4,5,6);
Что бы считать данные из файла используется, знакомая нам процедура, read, причём первым параметром должна идти файловая переменная, а затем через запятую переменные, в которые должны быть записаны данные из файла:
read(f,a,b,c,d);
Когда работа с файлом закончена, его необходимо обязательно закрыть, иначе при завершении работы программы, если файл остался открытым, могут возникнуть проблемы в файловой системе жёсткого диска. Закрывается файл с помощью процедуры Close(f):
close(f);
Если необходимо открыть уже существующий файл, не удалив его, используется процедура Reset(f):
reset(f);
Теперь пример целой программы:
Type Tf = file of integer;
var f:Tf;
a,b,c,d:integer;
begin
assign(f,‘c:111111.int’);
rewrite(f);
write(f,3,4,5,6);
close(f);
reset(f);
read(f,a,b,c,d);
writeln(a,b,c,d);
close(f);
end.
_____________________________
3456
В данном примере запись и чтение данных происходит по порядку. Иногда приходится считывать данные из какого-либо места в файле. Для этого существует следующее понятие: файловый указатель. При открытии или создании файла файловый указатель устанавливается в начало файла и указывает позицию 0. Когда мы записываем данные в файл, после записи каждого элемента файловый указатель перемещается на одну позицию. При чтении данных происходит то же самое, после чтения каждого элемента файловый указатель перемещается на одну позицию вперёд.
Для работы с файловым указателем существуют следующие процедуры и функции:
procedure Seek(f: file of T; n: LongInt);
Устанавливает текущую позицию файлового указателя в типизированном файле f на элемент с номером n.
function FilePos(f: file of T): LongInt;
Возвращает текущую позицию файлового указателя в типизированном файле f.
function FileSize(f: file of T): LongInt;
Возвращает количество элементов в типизированном файле f.
Пример:
Type Tf = file of integer;
var f:Tf;
a,b,c,d:integer;
begin
assign(f,‘c:111111.int’);
reset(f);
seek(f,2); read(f,c);
seek(f,filepos(f)-3); read(f,a);
seek(f,filesize(f)-1);read(f,d);
seek(f,1); read(f,b);
close(f);
writeln(a,b,c,d);
end.
__________________________________
3456
В этом примере чтение данных из файла мы произвели не по порядку, используя процедуры и функции для работы с файловым указателем. Так же стоит сделать следующие замечания: как уже было сказано, первый элемент имеет нулевую позицию, соответственно второй элемент первую позицию и т.д. отсюда, что бы считать или записать первый элемент файловый указатель необходимо поставить в нулевую позицию, второй элемент – в первую и т.д. Стоит ещё добавить, что номер позиции последнего элементы будет равен количеству элементов в файле за вычетом единицы. И ещё одно, прежде чем считывать данные из файла, рекомендую всегда устанавливать файловый указатель в нужную позицию.
Записывать элементы в файл можно так же не по порядку, используя процедуры и функции для работы с файловым указателем. Если взять предыдущий пример, то просто вместо процедуры read подставить процедуру write. Как уже было сказано выше, при записи элемента файловый указатель смещается на одну позицию, при этом происходит стирание старого элемента и запись нового в то место, где находился файловый указатель.
Для чтения всех данных из файла, удобно пользоваться следующей функцией:
function Eof(f: FileType): boolean;
Возвращает True, если файловый указатель находится в конце файла f. Данная функция применима ко всем трём типам файлов. Пример:
Type Tf = file of integer;
var f:Tf;
temp:integer;
begin
assign(f,‘c:111111.int’);
reset(f);
While not eof(f) do
begin
read(f,temp);
write(temp);
end;
close(f);
end.
____________________________
3456
Далее приведу ещё ряд процедур и функций для работы с типизированными файлами:
function FilePos(f: file of T): LongInt;
Возвращает текущую позицию файлового указателя в типизированном файле f. Иногда возникает необходимость узнать текущую позицию файлового указателя. Например, если вы пишете не всю программу целиком, а какую-то подпрограмму, и при выходе из вашей подпрограммы файловый указатель необходимо вернуть в прежнее место:
var f:file of integer;
a,c:integer;
Procedure VivodFila;
var pos:longint;
temp:integer;
begin
pos:=filepos(f);
seek(f,0);
While not eof(f) do
begin
read(f,temp);
write(temp,‘ ‘);
end;
seek(f,pos);
end;
begin
assign(f,‘c:111111.int’);
reset(f);
seek(f,2);
VivodFila;
writeln;
read(f,a,c);
writeln(a,‘+’,c,‘=’,a+c);
close(f);
end.
____________________________
20 4 30 40
30+40=70
procedure Truncate(f: file of T);
Усекает типизированный файл f, отбрасывая все элементы с позиции файлового указателя.
var f:file of integer;
Procedure VivodFila;
//Процедура VivodFila описана в одном из предыдущих примеров
……………………
begin
assign(f,‘c:1234’);
rewrite(f);
write(f,1,2,3,4,5,6);
vivodFila;
writeln;
seek(f,3);
Truncate(f);
vivodFila;
close(f);
end.
_______________________
1 2 3 4 5 6
1 2 3
Текстовые файлы.
Когда речь начинала идти о типизированных файлах, было сказано, что типизированные файлы не могут содержать в себе строки переменной длины. Для того, что бы записывать в файл строки переменной длины существуют текстовые файлы. Как и с любыми файлами, работа с текстовыми файлами осуществляется через файловую переменную. Для объявления файловой переменной текстового файла используется слово Text:
Var f:text;
Аналогично типизированным файлам, необходимо связать файловую переменную с файлом с помощью процедуры Assign(f). После работы с файлом его необходимо закрыть процедурой close(f).
В отличие от типизированных файлов чтение и запись в текстовый файл происходит целиком. Нельзя записать данные в какое-либо место файла или считать данные из какого либо места. Поэтому для текстовых файлов процедура rewrite(f) создаёт новый файл, стирая старый, только для записи в него. Процедура reset(f) открывает текстовый файл только для чтения.
Чтение и запись данных в текстовый файл осуществляется с помощью, до боли знакомых нам, процедур Write, Writeln, Read, Readln. Так же первым параметром идёт файловая переменная, затем список через запятую констант или переменных (параметров).
Прежде чем вести речь о том, как пользоваться этими процедурами, необходимо узнать структуру тестового файла. Текстовый файл состоит из строк переменной длины. В конце каждой строки находится специальное сочетание символов с порядковыми номерами 13 и 10. Например, если мы добавим данное сочетание в середину строки, то при выводе на экран в этом месте строка разорвётся и текст начнётся с новой строки:
var s:string;
begin
s:=‘Привет’+chr(13)+chr(10)+‘всем!’;
write(s);
end.
______________________________________
Привет
всем!
Наглядно структуру текстового файла можно продемонстрировать следующим образом:
……………………#13#10
……………#13#10
…………………………………#13#10
…#13#10
Eof
В данном примере: Eof – признак конца файла, который присутствует в любом файле. Символ «#» – говорит о том, что на этом месте находится символ с порядковым номером, который идёт далее.
Теперь можно говорить о процедурах чтения и записи.
Процедура Write делает запись в текстовый файл, но не вставляет комбинацию символов #13#10. Следовательно, при записи данных с помощью только этой процедуры в текстовом файле окажется только одна строка.
Процедура Writeln делает запись в текстовый файл и вставляет комбинацию символов #13#10. Следовательно, после вызова данной процедуры вставляется признак конца строки, и следующая запись будет происходить в новую строку.
Процедура Read считывает данные из файла, но не делает переход на следующую строку. Что бы считать данные и перейти на следующую строку необходимо использовать процедуру Readln.
Пример:
var f:text;
s:string;
begin
assign(f,‘c:text.txt’);
rewrite(f);
write (f,‘Привет’);//Записываем строку в файл
Writeln(f,‘ всем!’);//Записываем строку в файл и переходим на следующую
writeln(f,‘Ура, ура!’);//Записываем строку в файл и переходим на
//следующую
close(f);
reset(f);
read(f,s);//считываем строку
writeln(s);
readln(f);//переходим на следующую строку
readln(f,s);//считываем строку и переходим на следующую
writeln(s);
end.
_________________________________________________________________________
Привет всем!
Ура, ура!
Данными процедурам можно записывать в текстовый файл не только строки, но и символы, т.е. данные типа char. Ни каких тонкостей и нюансов при этом нет, происходит это так же как и со строками.
Так же вместо строк и символов можно записывать числа целые и вещественные, при этом они автоматически будут форматироваться в строку для записи и обратно для чтения. Только будьте внимательны и следите за соответствием данных:
var f:text;
i:integer;
r:real;
begin
assign(f,‘c:text.txt’);
rewrite(f);
writeln (f,12);
Writeln(f,3.14);
close(f);
reset(f);
readln(f,i);
writeln(i);
readln(f,r);
writeln(r);
end.
_________________________
12
3.14
Так же в текстовый файл можно вписать множество, однако считать его можно будет только как строку:
const m:set of integer = [3..4,6,55..57];
var f:text;
s:string;
begin
assign(f,‘c:text.txt’);
rewrite(f);
writeln (f,m);
close(f);
reset(f);
readln(f,s);
writeln(s);
close(f);
end.
_________________________________________
[3,4,6,55,56,57]
Для того, что бы целиком считать текстовый файл удобно пользоваться уже знакомой нам функцией Eof:
var f:text;
i:integer;
s:string;
begin
assign(f,‘c:text.txt’);
rewrite(f);
//Создаем файл случайной длины со случайными значениями
For i:=1 to random(50) do
begin
write (f,random(1000):4,‘ ‘);
if i mod 10 = 0 then writeln(f);
end;
close(f);
//Выводим содержимое файла на экран
reset(f);
while not eof(f) do
begin
readln(f,s);
writeln(s);
end;
close(f);
end.
_________________________________________________________
420 562 614 705 959 901 757 734 115 238
389 307 599 625 981 906 682 865 597 934
127 300 324 747 806 814 559 175 837 759
478 490 827 424 346 819 285 726
И ещё одна специфическая процедура для работы с текстовыми файлами: Append(f) – открывает текстовый файл для дополнения, т.е. после открытия файла данной процедурой можно вписывать в него данные, при этом старое содержимое стёрто не будет, а запись будет происходить с того места, где файл был закончен. Поэтому если хотите начать запись с новой строчки, то возможно понадобиться добавить признак конца строки:
var f:text;
i:integer;
s:string;
begin
assign(f,‘c:text.txt’);
//Открываем файл для дополнения
Append(f);
writeln(f,chr(13),chr(10),‘Всё это случайные числа’);
close(f);
//Выводим содержимое файла на экран
reset(f);
while not eof(f) do
begin
readln(f,s);
writeln(s);
end;
close(f);
end.
________________________________________________________
420 562 614 705 959 901 757 734 115 238
389 307 599 625 981 906 682 865 597 934
127 300 324 747 806 814 559 175 837 759
478 490 827 424 346 819 285 726
Всё это случайные числа
В данном параграфе мы изучили типизированные и текстовые файлы и научились ими пользоваться.
Задачи.
1. Необходимо создать массив случайных целых чисел, записать его в файл, затем вывести его на экран из файла.
2. Создать с помощью программы текстовый файл (не менее 2-х строк). Добавить в него ещё одну строку с помощью процедуры Append. Вывести файл на экран.
3. Создать программу поиска слова в текстовом файле. Слово для поиска пользователь вводит с клавиатуры. Примечание: в предыдущем параграфе в 3-ей задаче необходимо было вывести в отдельную функцию процесс поиска слова в строке. При создании программы можно использовать данную функцию.
4. Написать функцию определения количества строк в текстовом файле. Написать функцию, считывающую определённую строку по номеру из текстового файла. Написать программу демонстрирующую работу данных подпрограмм.
5. Имеется текстовый файл со списком слов. Каждое слово находится в новой строчке. Необходимо отсортировать слова по алфавиту. Регистр букв не должен иметь значения. Примечание: для примера создать список не менее 20 слов.
Решение.
1.
Program Ispolzovanie_Massiva;
//Программа демонстрирует работу с типизированными файлами
const imya_file = ‘c:massiv.int’;//Константа содержит название файла
max = 30;// размер массива
var massiv: array [1..max] of integer;
f:file of integer;
i:integer;
begin
//Заполняем массив
for i:=1 to max do
massiv[i]:=random(1,1000);
//Записываем в файл
assign(f,imya_file);
rewrite(f);
for i:=1 to max do
write(f,massiv[i]);
close(f);
//Читаем массив из файла
assign(f,imya_file);
reset(f);
for i:=1 to max do
read(f,massiv[i]);
close(f);
//Выводим массив на экран
for i:=1 to max do
begin
write(massiv[i]:5);
if (i mod 10)=0 then writeln;//Создаем новую строчку
end;
end.
_________________________________________________________________________
920 288 950 972 812 413 244 579 112 357
513 855 943 299 292 694 51 976 309 973
457 561 45 855 308 284 511 119 146 809
2.
Program Sozdanie_textovogo_fayla;
//Программа создаёт текстовый файл, дополняет его и выводит его на экран
Var f:text;
s:string;
Begin
//Создаём текстовый файл
assign(f,‘c:Text.txt’);
Rewrite(f);
writeln(f,
‘В классе 20 учеников. Все ученики учатся по-разному. Одни ученики ‘+
‘являются отличниками или хорошистами, другие ученики троечники, учеников’+
‘ двоечников нет.’);
Writeln(f,‘В другом классе 22 ученика. Двоечников учеников тоже нет.’);
close(f);
//Добавляем в текстовый файл строку
Append(f);
Writeln(f,‘Всего в школе есть один ученик двоечник.’);
close(f);
//Выводим текстовый файл на экран
reset(f);
while not eof(f) do
begin
readln(f,s);
writeln(s);
end;
close(f);
end.
_________________________________________________________________________
В классе 20 учеников. Все ученики учатся по-разному. Одни ученики являются отличниками или хорошистами, другие ученики троечники, учеников двоечников нет.
В другом классе 22 ученика. Двоечников учеников тоже нет.
Всего в школе есть один ученик двоечник.
3.
Program Poisk_slova_v_fayle;
//Программа ищет слово в файле и выводит, сколько раз это слово встречается
Const imya_fayla = ‘c:Text.txt’;//файл в котором будем искать
Var f:text; //файловая переменная
sTemp, //Переменная для хранения текущей строки
s //Переменная для хранения слова для поиска
:string;
kolTek, //количество найденных слов в текущей строке
kol //количество найденных слов в файле
:integer;
//Функция находит количество слов s2, входящих в строку s1
Function Poisc(s1,s2:string):word;
var i,s:word;
begin
s:=0;
i:=1;
while i<length(s1)do
begin
if (PosEx(s2,s1,i)<>0)then
begin
s:=s+1;
i:=PosEx(s2,s1,i);
end;
i:=i+1;
end;
Poisc:=s;
end;
begin
Writeln(‘Введите слово для поиска’);
readln(s);
assign(f,imya_fayla);
reset(f);
//======================================
//ищем слово в файле
kol:=0;
while not eof(f) do
begin
readln(f,sTemp);
kolTek:=poisc(sTemp,s);
if kolTek <> 0 then kol:=kol+kolTek;
end;
//======================================
close(f);
Writeln;
Write(‘В текстовом файле “‘,imya_fayla,‘” слово “‘,s,‘” ‘);
if kol<>0 then write(‘встречается ‘,kol,‘ раз.’)
else write(‘невстречается.’);
end.
______________________________________________________________
Введите слово для поиска
ученик
В текстовом файле “c:Text.txt” слово “ученик” встречается 8 раз.
4.
Program Textovie_fayli;
//Программа содержит функцию выдающую количесвто строк в текстовом файле
//и функцию выдающую строку из файла по номеру
var kol_strok_v_fayle:integer; //содержит количество строк в файле
nomer_stroki:integer; //Номер строки для вывода
sn:string; //строка для вывода по номеру
//Функция определения количества строк в текстовом файле imya_fayla
function kol_strok(imya_fayla:string):integer;
var f:text;
kol:integer;
begin
kol:=0;
assign(f,imya_fayla);
reset(f);
while not eof(f) do
begin
inc(kol);
readln(f);
end;
kol_strok:=kol;
close(f);
end;
//Функция выдаёт строку из файла imya_fayla по её номеру n.
function stroka_po_nomeru(imya_fayla:string;n:integer):string;
var f:text;
i:integer;
sTemp:string;
begin
assign(f,imya_fayla);
reset(f);
for i:=1 to n do readln(f,sTemp);
stroka_po_nomeru:=sTemp;
close(f);
end;
begin
//Определяем количесвто строк в файле
kol_strok_v_fayle:=kol_strok(‘c:Text.txt’);
writeln(‘В текстовом файле “c:Text.txt” содержится ‘,
kol_strok_v_fayle,‘ строк.’);
//Выводим строку по её номеру
writeln(‘Введите номер строки для вывода.’);
readln(nomer_stroki);
If kol_strok_v_fayle < nomer_stroki then
writeln(‘В данном текстовом файле строки с таким номером нет.’)
else
begin
sn:=stroka_po_nomeru(‘c:Text.txt’,nomer_stroki);
write(‘Строка с номером ‘,nomer_stroki,
‘ содержит в себе следующее: “‘,sn,‘”‘);
end;
end.
_________________________________________________________________________
В текстовом файле “c:Text.txt” содержится 3 строк.
Введите номер строки для вывода.
2
Строка с номером 2 содержит в себе следующее: “В другом классе 22 ученика. Двоечников учеников тоже нет.”
5.
Program Sortirovka_slov;
//Программа сортирует список слов в текстовом файле по алфавиту
var f,fTemp:text;
sTemp,//Строка для временного хранения
s1,s2,//Предыдущая и следующая строки соответственно
s11,s22//Предыдущая и следующая строки соответственно в нижнем регистре
:string;
flg:boolean;//Если слова уже отсортированы то равна false
//Процедура для вывода списка на экран
Procedure vivod_spiska_iz_fayla;
begin
reset(f);
while not eof(f) do
begin
readln(f,sTemp);
write(sTemp);
if eof(f) then write(‘.’) else write(‘, ‘);
end;
Writeln;
close(f);
end;
begin
assign(f,‘c:Список.txt’);
assign(fTemp,‘c:Temp.txt’);
write(‘Имеем следующий список: ‘);
vivod_spiska_iz_fayla;
//Сортируем список
flg:=true;//Список ещё не отсортирован
while flg do
begin
reset(f);
readln(f,s1);
rewrite(fTemp);
flg:=false;//Если список уже отсортирован, то далее в True не установтся
While not eof(f) do
begin
readln(f,s2);
//Переводим строки в нижний регистр
s11:=LowerCase(s1);
s22:=LowerCase(s2);
//Если в нижнем регистре предыдущая строка больше следующей строки, то
//меняем строки местами и устанавливаем flg в true
if s11>s22 then
begin
flg:=true;
sTemp:=s1;
s1:=s2;
s2:=Stemp;
end;
writeln(fTemp,s1);//Записываем во временный файл
s1:=s2;
end;
writeln(fTemp,s2);//Дописываем последнюю строку
close(f);
close(fTemp);
//Заменяем исходный файл временным
erase(f);
rename(fTemp,‘c:Список.txt’);
end;
writeln;
write(‘После сортировки: ‘);
vivod_spiska_iz_fayla;
end.
_________________________________________________________________________
Имеем следующий список: пища, Несъедобное, единственный, выход, можно, более, незаметно, посторонний, предмет, Рот, палец, краешек, тарелка, Это, Волосок, масло, червяк, лист, салат, муха.
После сортировки: более, Волосок, выход, единственный, краешек, лист, масло, можно, муха, незаметно, Несъедобное, палец, пища, посторонний, предмет, Рот, салат, тарелка, червяк, Это.