Имена файлов и аргументы командной строки

Порядок выполнения лабораторной работы

1. Изучить теоретические сведения. Разобрать представленные примеры. Запустить первые четыре примера.

2. Получить вариант индивидуального задания у преподавателя. Предполается реализация двух задач разными способами: первый способ для первой задачи – использовать стандартные потоковые классы для решения задачи, второй способ для второй задачи – перегрузить операторы << и >> для работы со стандартными потоковыми классами.

3. Реализовать полученные задания. Для выбора решения задачи пользователем реализовать меню. Любое общение с пользователем должно сопровождаться поясняющимся текстом. Также в программе должно быть реализовано минимум 2 исключительных ситуации. Исключительные ситуации должны обрабатываться в отдельном классе. Обязательна оконная (формочная) реализация программы с использованием элементов управления.

4. Показать результат работы программы преподавателю.

5. Защитить лабораторную работу.

Требования к отчету

Отчет должен содержать:

1. Цель работы.

2. Задание.

3. Словесное описание исключительных ситуаций.

4. UML диаграмма классов.

5. Блок-схема программы.

6. Текст программы на языке C++ с комментариями.

7. Тесты (копии выходных форм программы/сформированных файлов).

8. Выводы.

Теоретические сведения

Потоковый ввод/вывод дисковых файлов

Для работы с дисковыми файлами необходимо подключение заголовочного файла <fstream>, содержащего наборы специальных классов:

- ifstream — для ввода,

- ofstream — для вывода,

- fstream — для чтения и записи данных в один и тот же файл.

Чтобы получить возможность работать с дисковым файлом, нужно открыть его с указанием режима доступа, который определяется значением константы open-mode класса ios.

Режим доступа Стандарт Действие
app нет открывает файл для дозаписи
ate(atend) да при открытии файла устанавливает файловый указатель на конец файла
binary(bin) да открыть файл в двоичном представлении
in да открыть файл для чтения (ввода)
nocreate нет если файл не существует, то новый файл не создается
noreplace нет если файл уже существует, файл не перезаписывается
out да открыть файл для записи (вывода)
trunc нет Открывает и усекает существующий файл. Новая информация замещает существующую

Текстовые файлы

Создание и запись.

Для создания текстового файла определяют объект класса ofstream и передают конструктору класса имя дискового файла в качестве первого параметра и режим доступа в качестве второго параметра:

ofstream out_file(“Out.txt”, ios::out);

Можно объявить константу, определяющую режим открытия файла, например:

const ios::open_mode=ios::out | ios::app;

После того, как предпринималась попытка открыть файл, следует убедиться в том, что файл открыт и готов для записи (или перезаписи):

if (! out_file) { cerr<<”Error: unable to write to out.txt”<<endl;

        exit(1);

      }

Все сказанное верно и для файлов, открываемых для чтения (или входных файлов):

ifstream in_file(“Input.txt”, ios::in);

if (! in_file) { cerr<<”Error: unable to open Input.txt”<<endl;

       exit(1);

      }

При работе с текстовыми файлами наиболее часто встречаются четыре действия:

- посимвольное чтение - посимвольная запись - построчное чтение - построчная запись

 

Посимвольное чтение текста.

Функция get(), которая является методом istream, применяется для посимвольного чтения текстового файла.

Пример 1. Посимвольное чтение файла и вывод его на экран.

 

# include <fstream>

# include <iostream>

using namespace std;

int main()

{

  setlocale(LC_ALL, "RUS");

  char sym;

  ifstream in_file("Input_file.txt", ios::in);

  if (!in_file) {

        cerr << "Error input file" << endl;

        exit(1);

  }

  while (in_file) {

        in_file.get(sym);

        cout << sym;

  }

  cout << endl;

  system("pause");

  return 0;

}

Посимвольная запись текста.

Функция put(), которая является методом ostream, позволяет осуществлять посимвольную запись данных в текстовый файл.

Пример 2.

# include <fstream>

# include <iostream>

# include <string>

using namespace std;

void main()

{

  setlocale(LC_ALL, "RUS");

  string guote = "Зорко одно лишь сердце.Самого главного глазами не увидишь.А.де Сент Экзюпери";

  ofstream out_file("Out_file.txt", ios::out);

  if (!out_file)    

  {

        cerr << "Error output file" << endl;

        exit(1);

  }

  for (int i = 0; i<guote.size(); i++)

        out_file.put(guote[i]);

  cout << "Конец записи" << endl;

  system("pause");

}

Построчное чтение файла.

Обычно построчное чтение и запись файлов работают быстрее посимвольных действий. Для чтения строки из файла воспользуемся функцией getline(), которая является методом класса ifstream. Функция читает строку (в том числе и разделители), пока не встретит символ новой строки ‘\n’, помещая ее в буфер (первый аргумент функции). Максимальный размер буфера задается как второй аргумент функции.

Пример 3.

# include <fstream>

# include <iostream>

using namespace std;

void main()

{

  setlocale(LC_ALL, "RUS");

  const int LEN = 80;

  char BUF[LEN];

  ifstream in_file("Input_file.txt", ios::in);

  if (!in_file)

  {

        cerr << "Error input file" << endl;

        exit(1);

  }

  while (in_file) {

        in_file.getline(BUF, LEN);

        cout << BUF << endl;

  }

  system("pause");

}

Построчная запись текста.

Пример 4.

# include <fstream>

# include <iostream>

# include <string>

using namespace std;

void main()

{

  setlocale(LC_ALL, "RUS");

  ofstream out_file("Out_file.txt", ios::out);

  if (!out_file) {

        cerr << "Error output file" << endl;

        exit(1);

  }

  out_file << "Я не знаю, где встретиться\n";

  out_file << "Нам придется с тобой, \n";

  out_file << "Глобус крутится - вертится, \n";

  out_file << "Словно шар голубой\n";

  cout << "Файл записан" << endl;

  system("pause");

}

Записываемые строки являются не объектами класса string, а строками типа *char, завершающимися символом ‘\n’.

Признак конца файла

Признак конца файла приходится искать в файлах, открытых для чтения. Этот признак устанавливается в тот момент, когда в файле не осталось больше данных, которые можно считать.

Признак конца файла анализируется в выражении вида

while (! In_file.eof()) { … }

Для этой цели нельзя пользоваться циклом

do { … } while (! In_file.eof()), поскольку файл может оказаться пустым.

Однако проверка на конец файла не анализирует ошибки, которые могут встретиться в процессе чтения файла.

Для проверки как конца файла, так и наличия ошибок при его чтении пользуются условием выхода из цикла:

while (In_file.good()) { … }

Оператор цикла

while (In_file) { … }

выполняется до тех пор, пока нет ошибок, в том числе и конца файла (EOF).

Имена файлов и аргументы командной строки

В приведенных выше примерах были использованы файлы с фиксированными именами. Однако более удобны программы, в которых имена файлов для чтения или записи можно ввести с клавиатуры или задать в качестве аргументов командной строки.

Пример 5.

# include <fstream>

# include <iostream>

# include <stdlib.h>

using namespace std;

int main(int argc, char *argv[])

{

  char I;

  char c;

  if (argc <= 1)

  {

        cout << "usage: primer.exe filename1 [filename2]" << endl;

        system("pause");

        return 1;

  }

  ifstream file;

  for (I = 1; I <= argc - 1; I++)

  {

        file.open(argv[I]);

        if (!file.is_open())

        {

               cout << "Bad file" << endl;

               system("pause");

               return 1;

        };

        cout << "file " << argv[I] << endl;

        while (file)

        {

               c = file.get();

               cout << c;

        };

        file.close();

  }

  cout << endl;

  system("pause");

  return 0;

}

Для работы с файловыми потоками любого из стандартных типов, нужно перегрузить операторы ввода и вывода под требуемый тип данных или воспользоваться шаблоном класса, задаваемым с помощью ключевого слова template.

Пример 6.

Файл myclass.h

#include <iostream>

using namespace std;

 

class myclass

{

  public:

        int x;

        float y;

        friend ostream& operator << (ostream& out, myclass& m);

        friend istream& operator >> (istream& out, myclass& m);

        myclass(int x_in, float y_in);

        myclass(void);

};

 

Файл myclass.cpp

#include "myclass.h"

 

myclass::myclass(int x_in, float y_in)

{

  x = x_in;

  y = y_in;

}

 

myclass::myclass(void)

{

  x = 0;

  y = 0.0;

}

 

ostream& operator << (ostream& out, myclass& m)

{

  out << m.x << ' ' << m.y << endl;

  return out;

}

istream& operator >> (istream& in, myclass& m)

{

  cout << "Введите X: ";

  in >> m.x;

  cout << "Введите Y: ";

  in >> m.y;

  return in;

}

 

Главный модуль

#include "myclass.h"

 

 

int _tmain(int argc, _TCHAR* argv[])

{

  setlocale(LC_ALL, "RUS");

  myclass m1(5, 6.3);

  cout << "m1: " << m1;

  myclass m2;

  cout << "m2: " << m2;

  cout << "Введиту m2:" << endl;

  cin >> m2;

  cout << "m2: " << m2;

  myclass m3 (3, 6.9);

  cout << "m3: " << m3;

  cout << "Введиту m3:" << endl;

  cin >> m3;

  cout << "m3: " << m3;

  system("pause");

  return 0;

}

 

Контрольные вопросы

1) Что такое поток?

2) Что представляет собой файловый указатель?

3) Перечислить режимы доступа к файлу.

4) Как открыть и как закрыть файл?


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: