Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Функции стандартного ввода.docx
Скачиваний:
1
Добавлен:
17.11.2019
Размер:
538.07 Кб
Скачать

Работа с бинарным файлом

Такие файлы, в отличие от потоковых, создаются в определенной логической структуре и поэтому должны читаться в переменную той же структуры. Пример программы приведен в листинге 9.14, результат работы программы показан на рис. 9.10.

Листинг 9.14

// 40.срр : Defines the entry point for the console application.

#include "stdafx.h"

#include <iostream> //for cin, cout

#include <fstream>

#include <conio.h>

#include <stdio.h>

void _tmain()

{

using namespace std; /*используется стандартное пространство имен*/

/*данные о сотрудниках*/

struct Blocknotes

{

char name[30];

char phone[15];

int age;

}b[2]={

"Smit", "123456", 45,

"Kolly", "456789", 50

}; //инициализация массива структур

//запись данных в файл

ofstream FILE;

FILE.open("Block", ios::binary);

for(int i=0; i<2; i++)

FILE.write((char *)&b[i], sizeof(b[i]));

FILE.close();

//чтение данных из файла

ifstream FILE1;

FILE1.open("Block", ios::binary);

Blocknotes bb[2];

int i=0;

while(!FILE1.eof())

{

if(i==2)

goto m;

FILE1.read((char *)&bb[i], sizeof(bb[i]));

cout << "string" << i << " " << bb[i].name <<" " << bb[i].phone << " " << bb[i].age << endl;

i++;

}

m: FILE1. close ();

system("DEL BLOCK");

_getch();

}

Рис. 9.10. Результат работы программы листинга 9.14

Пояснений требуют следующие моменты:

  • запись FILE.write((char *)&b[i], sizeof(b[i]));

Здесь для записи используется функция буферизированного вывода write(). где первым аргументом является указатель на структуру, из которой мы должны записывать данные. Этот указатель равен адресу структуры, т. е. &b[i]. Но в потоке все данные хранятся побайтно, поэтому тип указателя char (здесь идет принудительное преобразование типа). Второй аргумент— длина записи, она определяется стандартной функцией sizeof();

  • system ("DEL BLOCK ") ; — этой функцией удаляется рабочий файл;

  • оператор goto применен для подстраховки от превышения индекса массива bb[].

9.2.3 Стандартный ввод/вывод в C++

Общие положения

Стандартный ввод/вывод является частным случаем файлового ввода/вывода. При файловом вводе/выводе мы объявляли экземпляры соответствующих поточных классов, а затем пользовались методами и операциями: << , >>. Но как мы видели в начале этой главы, классы istream, ostream, лежащие в основе поточных классов, содержат стандартные объекты-экземпляры классов с именами cout (экземпляр класса для стандартного ввода), cin (экземпляр класса для стандартного вывода) и сегг (экземпляр класса для стандартного вывода сообщений об ошибках).

При запуске любой программы на языке C++ эти стандартные потоки определены (открыты) и по умолчанию назначены на стандартное вводное устройство — клавиатуру (cin), на стандартное выводное устройство — экран (cout и сегг). Причем все эти устройства синхронно связаны с соответствующими указателями stdin, stdout, stderr. Так что работа со стандартным вводом/выводом сводится к тому, что вместо задаваемых пользователем имен экземпляров соответствующих классов задаются имена стандартных экземпляров классов: cin, cout. Открывать ничего не надо, надо только использовать операции <<, >> и операции форматирования. Если мы пишем имена переменных, из которых выводятся или в которые вводятся данные, то по умолчанию для ввода/вывода используются определенные форматы. Например, запишем:

cout << i;

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

Запишем:

cin >> i >> j >> s;

где i, j, s описаны, соответственно, как int, float, char. В записи не видно форматов, но при вводе значений этих переменных с клавиатуры (после ввода каждого значения надо нажимать <Enter>) их форматы будут учтены.

Стандартный вывод cout

Объект cout направляет данные в буфер-поток, связанный с объектом stdout, объявленным в файле stdio.h. По умолчанию стандартные потоки С и C++ синхронизированы.

При выводе данные могут быть отформатированы с помощью функций-членов класса или манипуляторов. Их перечень приводится в табл. 9.2.

Примечание

Манипуляторы, начинающиеся с "no" (noshowpos и т. п.), имеют обратное действие по отношению к манипуляторам с такими же именами, но без приставки "no". В графе "Описание" у таких манипуляторов проставлены пробелы.

Таблица 9.2. Манипуляторы и функции стандартного ввода/вывода в C++

Манипуляторы

Функции-члены класса

Описание

showpos

setf(ios::showpos)

Выдает знак плюс у выводимых положительных чисел

noshowpos

unsetf(ios::showpos)

showbase

setf(ios::showbase)

Выдает базу системы счисления в выводимом числе в виде префикса

noshowbase

unsetf(ios::showbase)

uppercase

setf(ios::uppercase)

Заменяет символы нижнего регистра на символы верхнего регистра в выходном потоке

nouppercase

unsetf(ios::uppercase)

showpoint

setf(ios::showpoint)

Создает символ десятичной точки в сгенерированном потоке с плавающей точкой (в выводимом числе)

noshowpoint

unsetf(ios::showpoint)

boolalpha

setf(ios::boolalpha)

Переводит булевый тип в символьный

noboolalpha

unsetf(ios::boolalpha)

unitbuf

setf(ios::unitbuf)

Сбрасывает буфер вывода после каждой операции вывода

nounitbuf

unsetf(ios::unitbuf)

internal

setf(ios::internal, ios::adjustfield)

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

left

setf(ios::left, ios :: adjustfield)

Добавляет символы-заполнители с конца числа (сдвигая число влево)

right

setf(ios::right,ios:: adjustfield)

Добавляет символы-заполнители с начала числа (сдвигая число вправо)

dec

setf(ios::dec, ios:: basefield)

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

hex

setf(ios::hex,ios:: basefield)

Переводит базу вводимых или выводимых целых чисел в шестнадцатеричную (введенные после этого манипулятора данные будут выводиться как шестнадцатеричные)

oct

setf(ios::oct,ios:: basefield)

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

fixed

setf(ios::fixed, ios :: floatfield)

Переводит выход с плавающей точкой в выход с фиксированной точкой

scientific

setf(ios::scientific, ios:: floatfield)

Выдает числа с плавающей точкой в виде, используемом в научных целях: например, число 23450000 будет записано как: 23.45е6

setbase(int base)

Преобразует ввод целых чисел в тип base, где параметр base может быть одним из чисел 8, 10 или 16

fill(с)

setfill(char_type c)

Задает символ заполнения при выводе данных

precision(n)

setprecision(int n)

Задает точность вывода данных (количество цифр после точки)

setw(int n)

width(n)

Задает ширину поля для выводимых данных (количество символов)

endl

Вставляет символ новой строки ('\n') в выходную последовательность символов и сбрасывает буфер ввода

ends

Вставляет символ '\0' в выходную последовательность символов

flush

flush( )

Сбрасывает буфер вывода

ws

Задает пропуск пробелов при вводе

Значения по умолчанию:

  • precision() —6;

  • width() —0;

  • fill() — пробел.

В листинге 9.15 приведен пример программы с применением объекта cout (все пояснения можно найти в комментариях). Результат работы программы представлен на рис. 9.11.

Листинг 9.15

// 41.срр : Defines the entry point for the console application.

#include "stdafx.h"

#include <iostream>

#include <iomanip> //включение манипуляторов

#include <conio.h>

// cout example

void _tmain()

{

using namespace std;

int i;

float f;

cout << "Enter i and f >" << endl;

//чтение целого числа и числа с плавающей точкой с устройства stdin

cin >> i >> f;

//вывод целого и переход на новую строку

cout << i << endl;

//вывод числа с плавающей точкой и переход на новую строку

cout << f << endl;

//вывод в шестнадцатеричной системе

cout << hex << i << endl;

//вывод в восьмеричной и десятичной системах

cout << oct << i << dec << i << endl;

//вывод i с указанием его знака

cout << showpos << i << endl;

//вывод i в шестнадцатеричной системе

cout << setbase(16) << i << endl;

/*вывод i в десятичной системе и дополнение справа символом @ до ширины в 20 символов (заполнение начинается от правой границы к левой). Если вы вводите, например, 45, то выведется 45@@@@@@@@@@@@@@@@@@*/

cout << setfill('@') << setw(20) << left << dec << i;

cout << endl;

//вывод того же результата в том же формате, но с использованием функций вместо манипуляторов cout.fill('@');

cout.width(20);

cout.setf(ios::left, ios::adjustfield);

cout.setf(ios::dec, ios::basefield);

cout << i << endl;

//вывод f в научной нотации с точностью 10 цифр

cout << scientific << setprecision(10) << f << endl;

//изменение точности до 6 цифр

cout.precision(6);

//вывод f и возврат к нотации с фиксированной точкой

cout << f << fixed << endl;

_getch();

} // _tmain()

Рис. 9.11. Результат работы программы листинга 9.15