Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Visual_C_console.pdf
Скачиваний:
34
Добавлен:
16.05.2015
Размер:
954.14 Кб
Скачать

132

typedef union

{

double n; long m[2];

} numb;

Такое описание создает тип данных numb, который может содержать элементы разных типов n и m. Память выделяется для размещения самого длинного из этих элементов (в данном случае для n, который занимает 8 байт). После этого можно объявить переменную этого типа, например,

numb scn;

Объединения в настоящее время применяются редко. Целесообразно вместо объединения применять оператор преобразования типов reinterpret_cast (см. параграф «Преобразование типов»).

Файлы

Под файлом обычно подразумевают блок информации, который пересылается или может быть перемещен с одного устройства на другое. Файл имеет имя, на которое налагаются ограничения операционной системы. В частности, в системе MS-DOS имя файла не может иметь длину более 8 символов и должно состоять из латинских букв, цифр и некоторых других символов. В системе Windows длина имени может достигать 254 символов и может содержать пробелы.

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

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

133

Существуют некоторые стандартные файлы. Так, клавиатура является стандартным устройством ввода, а дисплей стандартным устройством вывода. Для этих устройств в языке зарезервированы имена файлов соответственно stdin и stdout, кроме того, имеется файл с именем stderr, в который направляются сообщения об ошибках. Эти три файла открываются автоматически при запуске программы и для них можно переназначать источники и места назначения для перемещения информации. Например, можно вместо вывода на экран направить вывод в файл на жестком диске.

Одна и та же программа может работать с разными файлами, поэтому всегда надо указывать компьютеру, с каким именно файлом будет выполняться обработка на этот раз. Подключение файла к программе называется «открытием» файла. Открытие файла обеспечивает его связь с программой пользователя и запускает выполнение ряда операций, важнейшими из которых являются проверка на наличие на заданном устройстве указанного пользователем файла и готовность устройства к работе. Например, пользователь мог забыть вставить в дисковод компакт-диск с требуемым файлом.

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

Операции с файлом (чтение или запись) выполняются, начиная с текущей позиции в файле, которая непосредственно пользователем часто не используется. Например, при вводе чисел из файла будет вводиться то число, которое размещено, начиная с текущей позиции в файле, и заканчивается разграничителем, следующим (записанным) после числа (обычно это «белый пробел», которым является пробел, символ конца строки или символ табуляции). После выполнения этой операции текущая позиция автоматически устанавливается на следующее число.

Начальная установка текущей позиции в файле зависит от режима работы с файлом. При открытии файла в режиме чтения или записи

134

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

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

Текстовый файл обычно состоит из фраз (строк в понимании человека), которые составляются из слов. Слова разделяются разграничительными знаками – «белыми пробелами». При вводе таких разграничителей с помощью операции cin >>, система реагируют на эти символы, считая их разграничителями стандартных строк языка С++. Поэтому для ввода строк, содержащих белые пробелы, желательно использовать строки типа string. При выводе такой проблемы не существует.

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

#include <fstream> // Имя файла без расширения .h

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

Чтобы с помощью одной программы можно было обрабатывать разные файлы, в программе объявляется «внутреннее» имя файла, которое может быть связано с любым файлом на диске. На это внутреннее имя файла налагаются такие же требования, как и к обычным именам переменных языка С++. На внешние имена файлов налагаются ограничения используемой операционной системы. В ли-

135

тературе внутреннее имя файла часто называют «дескриптором файла».

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

ifstream inFil (fname);

Здесь внешнее имя файла fname является строкой символов типа char, задающей имя файла на диске, а inFil внутреннее имя файла. Тип ifstream предназначен для открытия файлов для ввода.

Режим может быть указан и явно: ifstream inFil(fname, ios::in);

Основных режимов 3:

in - файл открывается для ввода

out - файл открывается для вывода

app - файл открывается для добавления записей.

Для ввода может быть открыт только существующий файл, для вывода файл создается, но если такой файл существует, то он будет переписан (то есть уничтожен). В режиме app новые записи добавляются к существующему файлу, но если файл не существует, то он будет создан.

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

Для вывода на устройстве может не быть места для файла

Может существовать запрет для создания файла на указанном устройстве или в заданной папке.

Устройство физически не может выполнить операцию записи (например, попытка записи на компакт-диск типа R, или в модуль флэш-памяти с возможностью физической блокировки записи).

136

Ниже показаны примеры открытия файла с проверкой (inFil и outFil это произвольные внутренние имена для открываемых файлов).

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

ifstream inFil(fname);

if (!inFil) // Это равносильно inFil != 0

{

cout << "Не открыт файл" << fname;

_getch(); // Остановка экрана для чтения сообщения return 1;

}

А так файл можно открыть для вывода ofstream outFil(fname);

if (!outFil)

{

cout << "Не открыт файл" << fname; _getch();

return 1;

}

Если файл открыт, то для ввода и вывода предопределенных типов данных можно использовать перегруженные знаки операци сдвига (<< для вывода в файл и >> для ввода из файла). Например, если x переменная типа double, то для ее считывания из файла следует записать:

inFil >> x;

Сложнее выполняется ввод и вывод текста, поскольку в тексте, обычно, длина строк и слов переменная. В частности, операция >> обеспечивает ввод отдельных слов (разграниченных пробелами), но не целых строк.

Для ввода текстовой информации из файла можно использовать функции:

137 get(<строка>,<длина>) или get(<символ>) и

getline (<дескриптор файла>,<строка>, <разграничитель>).

Функция get при считывании строк считывает также и символ конца строки, но сохраняет его во входном потоке. Чтобы убрать этот символ надо записать (для открытого выше файла):

inFil.get();

При вводе с клавиатуры cin.get();

Для функции get() разграничителем является белый пробел (это клавиши ENTER, TAB и пробел), поэтому применение этой функции ограниченно. Например, если требуется просто прочитать текстовой файл и вывести его на экран, то проще всего это выполнить следующим способом:

//Имя открываемого файла, задано в директиве #define ifstream myFile(FNAME);

if (!myFile)

{

cout << "Не открыт файл" << FNAME; _getch();

return 1;

}

//Вывод содержимого текстового файла на экран

char ch;

while (inFile.get(ch)) cout << ch;

Для вывода с помощью операции добавить заголовочный файл пространство имен std.

cout в этом примере следует iostream и использовать

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

138

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

Ввод текста из файла в память программы (например, в матрицу) в этом случае выполняется с помощью функции getline (ниже в примерах подразумеватеся, что файл открыт с именем указателя на файл inFil).

Функция getline считывает строки типа string. (Для работы с такими строками требуется вставить директиву препроцессора

#include <string>

(без расширения имени файла .h)). Память для строк типа string выделяется автоматически. Максимальная длина строк типа string равна 4 Гбайт.

При вызове функции getline можно указать разграничитель строк. Тогда строка считывается до разграничителя, но последний к строке не приписывается (удаляется из входного потока). Для того, чтобы получить в этом случае текст в виде стандартных строк языка С++ применяют функцию c_str(), которая принудительно приписывает нулевой символ к концу строки.

Примечание: Если в функции getline указан разграничитель, отличный от конца строки (\n - этот разграничитель используется по умолчанию, и его можно не записывать), то символы конца строки оказываются внутри прочитанной строки (читается абзац), поэтому при выводе такого текста на экран автоматически будет осуществляться разбиение абзаца на строки.

Функциий getline удобно пользоваться, если требуется разбить входной поток на разные по смыслу элементы, которые в памяти программы будут храниться в объектах типа структур, например, глоссарий. Каждый элемент списка может состоять из нескольких слов, содержать разные знаки препинания и разграничители.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]