Исключения. Обработка исключений
Для обработки исключений применяется конструкция try...catch. Она имеет следующую форму:
try
{
инструкции, которые могут вызвать исключение
}
catch(объявление_исключения)
{
обработка исключения
}
В блок после ключевого слова try помещается код, который потенциально может сгенерировать исключение.
После ключевого слова catch в скобках идет параметр, который передает информацию об исключении. Затем в блоке производится собственно обработка исключения.
Пример [5].
#include <iostream>
double divide(int, int);
int main()
{
int x = 500;
int y = 0;
try
{
double z = divide(x, y);
std::cout << z << std::endl;
}
catch (...)
{
std::cout << "Error!" << std::endl;
}
std::cout << "The End..." << std::endl;
return 0;
}
double divide(int a, int b)
{
if (b == 0)
throw "Division by zero!";
return a / b;
}
Код, который потенциально может сгенерировать исключение - вызов функции divide помещается в блок try.
В блоке catch идет обработка исключения. Причем многоточие в скобках после оператора catch (catch(...)) позволяет обработать любое исключение.
В итоге когда выполнение программы дойдет до строки double z = divide(x, y);, будет сгенерировано исключение, поэтому последующие инструкции из блока try выполняться не будут, а управление перейдет в блок catch, в котором на консоль просто выводится сообщение об ошибке.
Потоки и система ввода-вывода
Базовые типы для работы с потоками
Объект типа ostream получает значения различных типов, преобразует их в последовательность символов и передает их через буфер в определенное место для вывода (консоль, файл, сетевые интерфейсы и т.д.).
Поток istream получает через буфер из определенного места последовательности символов (с консоли, из файла, из сети и т.д.) и преобразует эти последовательности в значения различных типов. То есть когда мы вводим данные (с той же клавиатуры в консоли), сначала данные накапливаются в буфере и только затем передаются объекту istream.
По умолчанию в стандартной библиотеке определены объекты этих классов - cout, cin, cerr, которые работают с консолью.
Запись в поток
Для записи данных в поток ostream применяется оператор <<. Этот оператор получает два операнда. Левый операнд представляет объект типа ostream, а правый операнд - значение, которое надо вывести в поток.
К примеру, по умолчанию стандартная библиотека C++ предоставляет объект cout, который представляет тип ostream и позволяет выводить данные на консоль [5]:
#include <iostream>
int main()
{
std::cout << "Hello" << std::endl;
return 0;
}
Чтение данных
Для чтения данных из потока применяется оператор ввода >>, который принимает два операнда. Левый операнд представляет поток istream, с которого производится считывание, а правый операнд - объект, в который считываются данные.
Для чтения с консоли применяется объект cin, который представляет тип istream.
#include <iostream>
int main()
{
int age;
double weight;
std::cout << "Input age: ";
std::cin >> age;
std::cout << "Input weight: ";
std::cin >> weight;
std::cout << "Your age: " << age << "\t your weight: " << weight << std::endl;
return 0;
}
Для вывода сообщения об ошибке на консоль применяется объект cerr, который представляет объект типа ostream [5]:
#include <iostream>
int main()
{ std::cerr << "Error occured" << std::endl;
return 0;
}
Файловые потоки. Открытие и закрытие
При операциях с файлом вначале необходимо открыть файл с помощью функции open(). Данная функция имеет две версии:
open(путь)
open(путь, режим)
Для открытия файла в функцию необходимо передать путь к файлу в виде строки. И также можно указать режим открытия. Список доступных режимов открытия файла:
ios::in: файл открывается для ввода (чтения). Может быть установлен только для объекта ifstream или fstream
ios::out: файл открывается для вывода (записи). При этом старые данные удаляются. Может быть установлен только для объекта ofstream или fstream
ios::app: файл открывается для дозаписи. Старые данные не удаляются.
ios::ate: после открытия файла перемещает указатель в конец файла
ios::trunc: файл усекается при открытии. Может быть установлен, если также установлен режим out
ios::binary: файл открывается в бинарном режиме
Если при открытии режим не указан, то по умолчанию для объектов ofstream применяется режим ios::out, а для объектов ifstream - режим ios::in. Для объектов fstream совмещаются режимы ios::out и ios::in
Пример [5]
std::ofstream out; // поток для записи
out.open("D:\\hello1.txt"); // окрываем файл для записи
std::ofstream out2;
out2.open("D:\\hello2.txt", std::ios::app); // окрываем файл для дозаписи
std::ofstream out3;
out2.open("D:\\hello3.txt", std::ios::out | std::ios::trunc); // установка нескольких режимов
std::ifstream in; // поток для чтения
in.open("D:\\hello4.txt"); // окрываем файл для чтения
std::fstream fs; // поток для чтения-записи
fs.open("D:\\hello5.txt"); // окрываем файл для чтения-записи
После завершения работы с файлом его следует закрыть с помощью функции close(). Также стоит отметить, то при выходе объекта потока из области видимости, он удаляется, и у него автоматически вызывается функция close [5].
#include <iostream>
#include <fstream>
int main()
{
std::ofstream out; // поток для записи
out.open("D:\\hello.txt"); // окрываем файл для записи
out.close(); // закрываем файл
std::ifstream in; // поток для чтения
in.open("D:\\hello.txt"); // окрываем файл для чтения
in.close(); // закрываем файл
std::fstream fs; // поток для чтения-записи
fs.open("D:\\hello.txt"); // окрываем файл для чтения-записи
fs.close(); // закрываем файл
return 0;
}