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;
}
}
}
Упражнения, тесты.
1. Пусть в программе записано следующее объявление: FILE *f; Что объявлено?
Варианты ответа:
1) указатель на область оперативной памяти для данных, хранящихся в файле на внешнем устройстве;
2) указатель на область оперативной памяти для структуры, поля которой зависят от конкретной задачи;
3) указатель на область оперативной памяти для характеристик (параметров) файла в виде структуры со стандартным именем FILE;
4) указатель на область внешней памяти для характеристик (параметров) файла в виде структуры со стандартным именем FILE;
2. С каким режимом (типом доступа к файлу), который записывается в функции fopen, можно создать новый файл?
Варианты ответа:
1) только “w”; 2) только “w+”; 3) “w” и “w+”; 4) только “a”; 5) только “a+”; 6) “ a ” и “ a+ ”; 7) “ w ”, “ w+ ”,“ a ”и “ a+ ”; 8) “ w ”и “ a ”;
9) “ w+ ”и “ a+ ”;
3. Даны следующие варианты кода:
1) FILE * f; fp=fopen("d:\\ANA\\cpp\\2005_06\\ bf1.dat","rb");
if (fp==NULL) { cout<<”Error “; exit(1); }
else cout<<”File is opened”;
2) if((fp=fopen("d:\\ANA\\cpp\\2005_06\\ bf1.dat","rb"))==NULL)
{ cout<<”Error “; exit(1); }
else cout<<”File is opened”;
3) FILE * f; fp=fopen("d:\\ANA\\cpp\\2005_06\\ bf1.dat","rb");
if (!fp) cout<<”File is opened”; else { cout<<”Error “; exit(1); }
4) FILE * f; if (fp=fopen("d:\\ANA\\cpp\\2005_06\\ bf1.dat","rb"))
{ cout<<”Error “; exit(1); }
else cout<<”File is opened”;
5) FILE * f; if (fp=fopen("d:\\ANA\\cpp\\2005_06\\ bf1.dat","rb"))
cout<<”File is opened”; else { cout<<”Error “; exit(1); }
6) FILE * f; if (fp==fopen("d:\\ANA\\cpp\\2005_06\\ bf1.dat","rb"))
cout<<”File is opened”; else { cout<<”Error “; exit(1); }
Какие из предложенных вариантов правильно открывают файл для чтения?
4. Пусть в программе записаны следующие объявления:
FILE *f; const m=5; int a[m]={10,-22, 30, 4,-50};
и открыт файл:
f=fopen(“…”, “w”);
Какие из следующих операторов (последовательностей операторов) из предоженнных правильно записывают все пять чисел массива a в файл?
1) fwrite (a, 5, 1, f);
2) fwrite (a, 20, 1, f);
3) fwrite (a, 10, 2,f);
4) fwrite(&a[0], sizeof(a), 1, f);
5) for(int i=0; i<n; i++) fwrite(a[i], sizeof(int), 1, f);
6) for(int i=0; i<n; i++) fwrite(a[i], sizeof(a), 1, f);
7) for(int i=0; i<n; i++) fwrite(&a[i], sizeof(int), 1, f);
8) for(int i=0; i<n; i++) fwrite(&a[i], sizeof(a), 1, f);
5. Пусть в программе записаны следующие объявления:
FILE *f; const m=20;
int a[m]={10,-22, 30, 4,-50, 6, 7,8,9, 100, 110, 12, 13, 14, 15};
и открыт файл:
f=fopen(“…”, “w”);
Сколько и какие целые числа запишем в файл с помощью одного вызова функции fwrite(a, 20, 2, f);?
Варианты ответа:
1) 10 первых чисел массива a;
2) 20 чисел: 15 записанных при объявлении массива и пять нулей;
3) 15 записанных при объявлении массива;
4) 10 чисел из второй половины массива а, то есть
110, 12, 13, 14, 15, 0, 0, 0, 0, 0;
5) Ошибка в fwrite, так как нет в массиве 20*2=40 чисел, которые функция пытается записать.
6. Как надо объявить массив а с элементами типа short, чтобы с помощью функции fwrite(a, 40, 1, f); весь этот массив был записан в файл?
Варианты ответа:
1) short a[10]; 2) short a[20]; 3) short a[80]; 4) short a[40]; 5) short a[5];
7. Пусть в программе записаны следующие объявления:
FILE *f;
struct ts { char fio[15]; int tel; } vs;
открыт файл (f=fopen(“…”, “w”);) и определены поля структуры.Какие из следующих операторов (последовательностей операторов) правильно записывают одну структуру (ФИО и телефон) в файл?
Варианты ответа:
1)fwrite(&ts, sizeof(vs),1,f); 2) fwrite(&vs, sizeof(ts),1,f);
3) fwrite(vs, sizeof(vs),1,f); 4) fwrite(vs, sizeof(ts),1,f);
5) fwrite(&vs, 20, 1, f); 6) fwrite(&vs, 15, 1, f);
7) fwrite(vs, 20, 1, f); 8) fwrite(vs, 15, 1, f);
8. Пусть в программе записаны следующие объявления:
FILE *f; const m=10; int a[m], b;
Пусть с помощью функции fwrite в файл записали 10 целых чисел типа int и файл открыт для чтения. Даны следующие варианты фрагмента программы:
1) for (int i=1; i<= m; i++)
{ fseek(f, (m-i)*sizeof(int), SEEK_SET);
fread(&b, sizeof(b), 1, arf);
// использование числа b …}
2) for (int i=m-1; i>=0; i--)
|
|
{ fseek(f, i*sizeof(int), 0);
fread(&b, sizeof(b), 1, arf);
// использование числа b …}
3) for (int i=1; i<= m; i++)
{ fseek(f, (m-i)*sizeof(int),1);
fread(&b, sizeof(b), 1, arf);
// использование числа b …}
4) for (int i=1; i<= m; i++)
{ fseek(f, -i*sizeof(b), SEEK_END);
fread(b, sizeof(b), 1, arf);
// использование числа b …}
5) for (int i=1; i<= m; i++)
{ fseek(f, -i*sizeof(int), 0);
fread(&b, sizeof(b), 1, arf);
// использование числа b …}
6) for (int i=1; i<=m;i++)
{ fseek(arf, (m-i)*sizeof(a), SEEK_SET);
fread(a,sizeof(a),1,arf);
// использование a …}
Какие из предложенных вариантов читают эти 10 чисел из файла в обратном порядке?
9. Пусть int p; FILE *f; Какие из следующих вызовов функции правильно определяют положение указателя чтения-записи созданного файла и запоминают его?
1) fgetpos (f, p); 2) fgetpos (f, &p); 3) fsetpos (f, p); 4) fsetpos (f, &p);
10. Пусть int *p=new int; FILE *f; Какие из следующих вызовов функции правильно устанавливают положение указателя чтения-записи созданного файла?
1) fgetpos (f, p); 2) fgetpos (f, &p); 3) fsetpos (f, p); 4) fsetpos (f, &p);
11. Пусть FILE *f; Какие из следующих вызовов функции правильно устанавливают положение указателя чтения-записи созданного файла на его начало?
1) rewind (f); 2) rewind (*f); 3) fseek(f, 0, 0); 4) fseek(f, 0, SEEK_END);
5) fseek(f, 0, 1); 6) ftell(f); 7) int p=0; fsetpos(f, &p); 8) int p=0; fsetpos(f, p);