ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 12) онлайн

Вычисление сдвига

Функция seekg() может использоваться в двух вариантах. Первый из них мы уже

видели — используется аргумент для указания позиции относительно начала

файла. Но можно использовать эту функцию и с двумя аргументами, первый из

которых — сдвиг относительно определенной позиции в файле, а второй опреде-

ляет позицию, начиная с которой отсчитывается этот сдвиг. Второй аргумент мо-

жет иметь три значения: beg означает начало файла, cur — текущую позицию ука-

зателя файла, end — это конец файла. Например, выражение

seekp(-10. ios::end);

установит указатель записи за 10 байтов до конца файла. То, как это выглядит,

условно изображено на рис. 12.5

Рис. 12.5. Функция seekp() с двумя аргументами

Вот пример, в котором используется двухаргументный вариант seekg() для

нахождения конкретного объекта (человека) класса person в файле GROUP.DAT

и для вывода данных об этом человеке.

Листинг 12.13. Программа SEEKG

// seekg.cpp

// Поиск конкретного объекта в файле

#include <fstream>        // для файловых потоков

#include <iostream>

using namespace std;

///////////////////////////////////////////////////////////

class person              // класс person

  {

Листинг 12.13 (продолжение)

  protected:

    char name[80];        // имя человека

    int age;              // его возраст

  public:

    void getData()        // получить данные о человеке

      {

      cout << "\n  Введите имя: "; cin >> name;

      cout << "  Введите возраст: "; cin >> age;

      }

    void showData(void)   // вывод данных о человеке

      {

      cout << "\n  Имя: " << name;

      cout << "\n  Возраст: " << age;

      }

  };

///////////////////////////////////////////////////////////

int main()

{

  person pers;                  // создать объект person

  ifstream infile;              // создать входной файл

  infile.open("GROUP.DAT",ios::in|ios::binary); // открыть

                                                // файл

  infile.seekg(0, ios::end);    // установить указатель на 0

                                // байт от конца файла

  int endposition = infile.tellg();      // найти позицию

  int n = endposition / sizeof(person);  // число человек

  cout << "\nВ файле " << n << " человек(а)";

 

  cout << "\nВведите номер персоны: ";

  cin >> n;

  int position = (n-1) * sizeof(person); // умножить размер

                         // данных под персону на число персон

  infile.seekg(position);               // число байт от начала

                         // прочитать одну персону

  infile.read( reinterpret_cast<char*>(&pers), sizeof(pers) );

  pers.showData();                      //вывести одну персону

  cout << endl;

  return 0;

}

 

Результат работы программы (при предположении, что файл GROUP.DAT — тот же, что в DISKFUN):

В файле 3 человек(а) Введите номер персоны: 2

Имя: Артур Возраст: 60

Для удобства работы пользователя мы нумеруем объекты (персоны), начиная с единицы, хотя в программе нумерация ведется с нуля. Поэтому персона №2 — это второй из трех человек, записи о которых имеются в файле.

 

31