С манипуляторами setiosflags и resetiosflags могут использоваться следующие ювнфлаги:
iоs::left — выравнивает данные по левому краю поля вывода;
ios::right — выравнивает данные по правому краю поля вывода;
ios::interval — выравнивает данные по ширине поля вывода;
ios::dec — выводит данные в десятичном формате;
ios::oct — выводит данные в восьмеричном формате;
ios::hex — выводит данные в шестнадцатеричном формате;
ios::showbase — добавляет префикс 0x к шестнадцатеричным значениям и О к восьмеричным значениям;
ios::showpoint — заполняет нулями недостающие знаки в значениях заданной длины;
ios::uppercase — отображает в верхнем регистре шестнадцатеричные и экспоненциальные значения;
ios::showpos — добавляет знак '+' перед положительными числами;
ios::scientific — отображает числа с плавающей запятой в экспоненциальном представлении;
ios::fixed — отображает числа с плавающей запятой в шестнадцатеричном представлении.
Дополнительную информацию можно получить из файла ios.h или из справочной системы компилятора.
Использование файлов для ввода и вывода данных
Потоки C++ обеспечивают универсальные методы обработки данных, поступающих с клавиатуры или диска, а также выводимых на экран и диск. В любом случае можно использовать либо операторы ввода и вывода, либо другие стандартные функции и манипуляторы. Дальнейшие разделы главы посвящены операциям открытия и закрытия файлов, которые сопровождаются созданием объектов ifstream и ofstream.
Объекты ofstream
Объекты, создаваемые для считывания или записи данных в файл, называются ofstream. Они являются производными от уже знакомого вам класса iostream.
Чтобы приступить к записи в файл, нужно сначала создать объект ofstream, а затем связать его с определенным файлом на диске. Использование объектов ofstream требует включения в программу файла заголовка fstream.h.
Примечание:Поскольку fstream содержит в себе iostream.h, нет необходимости в отдельном включении файла iostream.h.
Состояния условий
Объектами iostream поддерживаются флаги, отражающие состояние ввода и вывода. Значение каждого из этих флагов можно проверить с помощью функций, возвращающих TRUE или FALSE: eof(), bad(), fail() и good(). Функция eof() возвращает значение TRUE, если в объекте iostream встретился символ EOF (end of file — конец файла). Функция bad() возвращает значение TRUE при попытке выполнить ошибочную операцию. Функция fail() возвращает значение TRUE каждый раз, когда это же значение возвращает функция bad(), а также в тех случаях, когда операция невыполнима в данных условиях. Наконец, функция good() возвращает значение TRUE, когда все идет хорошо, т.е. все. остальные функции возвращают значение FALSE.
Открытие файлов для ввода-вывода
Для открытия файла myfile.cpp с помощью объекта ofstream нужно объявить экземпляр этого объекта, передав ему в качестве параметра имя файла:
ofstream fout("myfile.cpp");
Открытие файла для ввода выполняется аналогичным образом, за тем исключением, что для этого используется объект ifstream:
ifstream fin("myfile.cpp");
Обратите внимание, что в выражениях задаются имена объектов fout и fin, которые можно использовать так же, как объекты cout и cin соответственно.
Очень важным методом, используемым в файловых потоках, является функция-член close(). Каждый создаваемый вами объект файлового потока открывает файл для чтения или записи (или и для того и другого сразу). По завершении работы файл необходимо закрыть с помощью функции close(), чтобы впоследствии не повредить его и записанные в нем данные.
После связывания объектов потока с соответствующими файлами их можно использовать так же, как остальные объекты ввода-вывода. Пример использования объектов для обмена данными с файлами показан в листинге 16.16.
Листинг 16.16. Открытие файла для чтения и записи
1: #include <fstream.h>
2: int main()
3: {
4: char fileName[80];
5: char buffer[255]; // для ввода данных пользователем
6: cout << "File паше: ";
7: cin >> fileName;
8:
9: ofstream fout(fileName); // открытие файла для записи
10: fout << "This line written directly to the file...n";
11: cout << "Enter text for the file: ";
12: cin.ignore(1,'n'); // пропускает символ разрыва строки после имени файла
13: cin.getline(buffer,255); // принимает данные, введенные пользователем,
14: fout << buffer << "n"; // и записывает их в файл
15: fout.close(); // закрывает файл, после чего его вновь можно открыть
16:
17: ifstream fin(fileName); // открывается тот же файл для чтения
18: cout << "Here's the contents of the file:n";
19: char ch;
20: while (fin.get(ch))
21: cout << ch;
22:
23: cout << "n*** End of file contents.***n";
24:
25: fin.close(); // не забудь закрыть файл в конце программы
26: return 0;
27: }
Результат:
File name: test1
Enter text for the file: This text is written to the file!
Here's the contents of the file: This line written directly to the file...
This text is written to the file!
***End of file contents.***
Анализ: В строке 4 создается массив для записи имени файла, а в строке 5 — еще один массив для временного хранения информации, вводимой пользователем. В строке 6 пользователю предлагается ввести имя файла, которое записывается в массив fileName. В строке 9 создается объект ofstream с именем fout, который связывается с введенным ранее именем файла. В результате происходит открытие файла. Если файл с таким именем уже существует, содержащаяся в нем информация будет замещена.
Строкой 10 введенный текст записывается прямо в файл, а в строке 11 пользователю вновь предлагается ввести новый текст. Символ разрыва строки, оставшийся в буфере после ввода имени файла, удаляется строкой 12, после чего все введенные пользователем данные записываются в массив в строке 13. Введенный текст записывается в файл вместе с символом разрыва строки, а затем в строке 15 этот файл закрывается.
В строке 17 файл открывается заново, но в этот раз для чтения, и его содержимое посимвольно вводится в программу в строках 20—21.
Настройка открытия файла объектом ofstream
По умолчанию при связывании объекта ofstream с именем файла создается новый файл с указанным именем, если таковой не существует, или удаляется содержимое уже существующего файла с таким же именем. Чтобы изменить установки по умолчанию, используется второй аргумент конструктора объекта ofstream.
Для второго аргумента можно устанавливать следующие константные значения:
• ios::app — добавляет данные в конец файла вместо удаления всего содержимого файла;
• ios::ate — переводит точку ввода в конец файла, но у вас есть возможность вводить новые данные в любом месте файла;
• ios::trunc — устанавливается по умолчанию; полностью удаляет (отбрасывает) текущее содержимое файла;
• ios::nocreate — если файл не существует, операция открытия не выполняется;
• ios::noreplace — если файл уже существует, операция открытия не выполняется.
Имена констант являются аббревиатурами выполняемых действий: app — apend (добавить), ate — at end (в конец), trunc — truncate (отбросить) и т.п.
Листинг 16.17 является модификацией листинга 16.16 с установкой опции добавления данных в файл при его повторном открытии.
Листинг 16.17. Добавление данных в конец файла
1: #include <fstream.h>
2: int main() // возвращает 1 в случае ошибки
3: {
4: char fileName[80];
5: char buffer[255];
6: cout << "Please re-enter the file name: ";
7: cin >> fileName;
8:
9: ifstream fin(fileName);
10: if (fin) // файл уже существует?
11: {
12: cout << "Current file contents:n";
13: char ch;
14: while (fin.get(ch))
15: cout << ch;
16: cout << "n***End of file contents.***n";
17: }
18: fin.close();
19:
20: cout << "nOpening " << fileName << " in append mode...n";
21:
22: ofstream fout(fileName,ios::app);
23: if (!fout)
24: {
25: cout << "Unable to open " << fileName << " for appending.n";
26: return(1);
27: }
28:
29: cout << "nEnter text for the file: ";
30: cin.ignore(1,'n');
31: cin.getline(buffer,255);
32: fout << buffer << "n";
33: fout.close();
34:
35: fin.open(fileName); // переопределение существующего объекта fin!
36: if (!fin)
37: {
38: cout << "Unable to open " << fileName << " for reading.n";
39: return(1);
40: }
41: cout << "nHere's the contents of the file:n";
42: char ch;
43: while (fin.get(ch))
44: cout << ch;
45: cout << "n***End of file contents.***n";
46: fin.close();
47: return 0;
48: }
Результат:
Please re-enter the file name: test1
Current file contents:
This line written directly to the file...