
- •Списки §1. Общие сведения о списках
- •§2. Создание списка
- •§3. Просмотр и анализ списка
- •3.1. Просмотр и анализ списка целых чисел.
- •3.2. Просмотр и анализ списка одномерных массивов.
- •§6. Сравнительный анализ списков.
- •§1. Порядок работы с файлом
- •1.1. Потоки и файлы
- •1.2. Объявление файла
- •1.3. Открытие файла.
- •1.4. Закрытие файла.
- •§2. Работа с текстовым файлом
- •2.1. Посимвольная работа с текстовым файлом
- •Int fputc(int ch, file *stream)
- •2.2. Построчная работа с текстовым файлом
- •§3. Функции блокового ввода/вывода
- •3.1. Экономические задачи с использованием файлов
- •3.2. Математические задачи с использованием файлов
- •§4. Прямой (произвольный) доступ к файлу
- •4.1. Функция fseek()
- •4.2. Замена записи. Функции ftell, fgetpos, fsetpos, rewind.
- •Пример. В файл записать координаты точек плоскости. Найти две (любые) точки с наибольшим расстоянием между ними. Массив для хранения координат всех точек не использовать.
- •Упражнения, тесты.
- •Функции (дополнительные возможности)
- •§1. Функции с переменным количеством параметров.
- •§2. Указатели на функции.
- •§3. Массив указателей на функции.
- •§4. Введение в рекурсивные функции.
- •Упражнения, тесты.
- •Void Fun1 (float); void Fun2(float); void Fun3(float);
- •Лабораторная работа № 12.
- •Команды препроцессора (директивы компиляции)
- •§1. Директива define (замены в тексте)
- •Простое макроопределение (макрос)
- •Макрос с аргументами.
- •Директива #undef.
- •§2. Директива #include (включение файлов).
- •§3. Директивы условной компиляции.
- •Директива #if.
- •Директивы #ifdef и #ifndef.
- •Упражнения, тесты
- •История развития технологий программирования
- •§1. Программирование в машинных кодах и на языках символического кодирования
- •§2. Языки высокого уровня. Структурное и модульное программирование
- •§3. Интегрированные системы программирования.
- •§4. История и идеи объектно-ориентированного программирования.
- •§5. Программирование для Windows. Визуальное программирование.
- •Литература
- •Оглавление Предисловие………………………………………………………….…………………3
- •Г л а в а 4. Структуры и другие типы, определяемые пользователем.84
- •Г л а в а 6. Файлы ………………………………………………………..154
- •Г л а в а 7. Функции (дополнительные возможности) ………………190
- •Г л а в а 9. История развития технологий программирования ……220
4.2. Замена записи. Функции ftell, fgetpos, fsetpos, rewind.
В предыдущий проект (п. 4.1) добавим ещё одну функцию, которая в файле одномерных массивов меняет массив с номером nChange. Замена выполняется в следующей последовательности:
void MyChange(int nChange)
{
// nChange — номер массива (записи), который меняем
// 1) Открываем в режиме "rb+".
arf= fopen("d:\\ANA\\cpp\\2004_05\\farr2.dat ", "rb+");
// 2) Переходим на начало массива с номером nChange
fseek(arf, (nChange-1) * sizeof(a), 0 );
/* 3) Запоминаем номер первого байта начала массива c номером nChange Нумерация байт с начала файла */
long p; p=ftell(arf); // or fgetpos(arf,&p);
cout<<endl<<"p="<<p<<endl; // p=20, если nChange=2
// 4) Читаем массив c номером nChange в оперативную память
fread(a, sizeof(a), 1, arf ) ;
printf("\n Массив, который будем менять");
/* 5) Выводим прочитанный массив и меняем его по заданному алгоритму */
for(j=0;j<m;j++)
{ printf("%d ",a[j]);
a[j]=a[j]*10;
}
/* 6) После выполнения функции fread указатель чтения-записи переместился “вперёд” к концу файла на один массив, т. е. на начало следующего массива с номером nChange+1. Поэтому устанавливаем позицию указателя чтения-записи на начало того же уже прочитанного массива c номером nChange, чтобы на это место записать изменённый массив. В нашем примере для наглядности при выводе каждый элемент увеличили в 10 раз.*/
fsetpos(arf,&p);
/* 7) На место старого массива записываем новый, изменённый массив. */
fwrite(a,sizeof(a),1, arf);
/* Запоминаем номер первого байта массива, следующего после изменённого, т.е. 40, если. nChange=2 Заметим, что в этом простом примере это можно не делать.*/
fgetpos(arf,&p); // или p=ftell(arf);
// Переходим на начало файла для дальнейшего его чтения
rewind(arf);
fread(a,sizeof(a),1,lf);
while (!feof(lf))
{ printf("\n"); for(j=0;j<m;j++) printf("%d ",a[j]);
fread(a,sizeof(a),1,lf);
}
/* Чтение файла, а, значит, и переход в его начало можно здесь опустить, так как в предыдущем пункте 4.1 была составлена функция для чтения. Её можно вызвать при необходимости. */
fclose(lf);
}
Пример. В файл записать координаты точек плоскости. Найти две (любые) точки с наибольшим расстоянием между ними. Массив для хранения координат всех точек не использовать.
struct TPoint {
float x,y;
} Point;
FILE *fP;
// Вычисление расстояния между двумя точками
float MyDist(TPoint p1, TPoint p2)
{ return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
// Создание файла
void MyCREATE()
{ clrscr(); int k=0;
if((fP=fopen ("d:\\ana\\cpp\\C++Lections2semestr\\files\\fPoints.dat","wb"))==NULL)
{ printf("Error\n");
return ;
}
else printf("File was opened for creating\n");
cout<<"x=1000 -- exit\n";
do {
printf("x="); scanf ("%f",&Point.x);
if (Point.x==1000) break;
printf("y="); scanf("%f", &Point.y);
fwrite(&Point,sizeof(Point),1,fP);
k++; // Счётчик количества точек
}
while (1);
printf("\n Writed %3d records\n",k);
fclose(fP);
}
/* Просмотр файла. Кроме этого, функция находит количество точек, координаты которых записаны в файле. Это количество затем будет передано в функцию поиска MyFind. Поэтому функцию MyRead надо выполнить (вызвать) перед MyFind. */
long MyREAD()
{ int n=0; clrscr();
if ((fP=fopen
("d:\\ana\\cpp\\C++Lections2semestr\\files\\fPoints.dat","rb"))==NULL)
{ printf("Error\n");
return -1;
}
else printf("File was opened for reading\n");
fread (&Point, sizeof(Point),1,fP);
while (!feof(fP))
{ n++; // Счётчик количества точек
printf("%6.1f",Point.x);
printf("%6.1f",Point.y);
fread (&Point, sizeof(Point),1,fP);
} fclose(fP);
printf("\n Read %d records\n ",n);
return n;
}
/* Функция находит две (любые) точки с наибольшим расстоянием между ними. В функцию передаём найденное в предыдущей функции количество точек. Функция возвращает координаты двух найденных точек (переменные типа структуры p1 и p2) и расстояние между ними (dres). */
void MyFIND(int n,TPoint &p1, TPoint &p2, float &dres)
{ TPoint Point1, Point2; float d; clrscr();
if((fP=fopen ("d:\\ana\\cpp\\C++Lections2semestr\\files\\fPoints.dat","rb"))==NULL)
{ printf("Error\n");
return ;
}
else printf("File was opened for finding\n");
long pos=0; dres=0;
for (int i=1; i<=n-1; i++)
{
/* Устанавливаем указатель чтения-записи в позицию, начиная с которой будем читать структуру (координаты одной точки) для сравнения со всеми далее расположенными точками в файле. Первый раз должны читать координаты первой точки. Поэтому pos =0. Далее будем использовать позицию, полученную с помощью функции fgetpos. */
fsetpos(fP,&pos);
fread (&Point1, sizeof(Point1),1,fP);
/* Запоминаем позицию в файле, чтобы, прочитав координаты всех точек, вернуться к этой точке. */
fgetpos(fP,&pos);
/* Читаем координаты точек до конца файла*/
fread (&Point2, sizeof(Point2),1,fP);
while (!feof(fP))
{
/* Находим расстояние от прочитанной точки до ранее фиксированной точки Point1… */
d=MyDist(Point1, Point2);
cout<<d<<" "; // … для контроля выводим его…
// … и сравниваем его с наибольшим расстоянием.
if (d>dres)
// Запоминаем координаты двух точек и расстояние между ними
{dres=d; p1=Point1; p2=Point2;
}
fread (&Point2, sizeof(Point2),1,fP);
}
}
fclose(fP);
}
int main()
{ int flag=1; long n=0; TPoint P1,P2; float D;
while (flag)
{ cout << "\n 1 -- CREATE"<<
"\n 2 -- LOOK"<<
"\n 3 -- FIND"<<
"\n 0 -- EXIT"<<endl;
cin>>flag;
switch (flag)
{ case 1: MyCREATE(); break;
case 2: n=MyREAD(); break;
case 3:
/* Напоминаем, что если не читали файл, то и не получили количество точек в файле. В таком случае необходимо выполнить второй пункт меню */
if (n==0) printf("\n n=0. Do number 2");
else { MyFIND(n,P1,P2, D);
printf("\n Result: x1=%6.1f y1=%6.1f",
P1.x, P1.y);
printf(" x2=%6.1f y2=%6.1f Dist=%8.3f",
P2.x, P2.y, D); break;
case 0: return 0;
}
}
}