Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Способы ввода/вывода в С++

Содержание:

Введение

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

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

В большинстве языков программирования операции по вводу-выводу встроены в сам язык. Примером таких языков будет Pascal и Basic, в них присутствуют соответствующие операторы PRINT, write in они в ходят в так называемы словари языков. В языке C или C++ отсутствуют операции ввода и вывода, встроенных в сам язык. В ключевых словах мы сможем найти for и if, но ничего что могло относится к вводу или выводу. Это предоставило свободу разработчикам компиляторов в проектировании функций ввода-вывода. Для организации ввода-вывода С++ полагается на решения из языка C, Это решение представляет собой набор классов определенных в заголовочных файлах iostream, fstream. [1]

В стандартном языке C++ используется два метода ввода-вывода информации:

- Традиционная система ввода-вывода, которая была унаследована от языка C;

- С помощью STL потоков (Standart Template Library). [2]

1. Ввод и вывод в языке С++

В С++ ввод-вывод реализован с помощью поточных классов, которые содержат данные и методы работы с файлами для ввода-вывода информации. Поточные классы берут свое начало и наследуют функционал от класса IOS. Для написания программы с использование ввода/вывода на языке программирования C++ необходимо выполнить в программе:

#include <fstream>

Класс fstream происходит от двух классов ostream и istream.

Ввод и вывод в С++ организован с помощью так называемых поточных классов, содержащих данные и методы работы с файлами по вводу/выводу. Поточные классы происходят от общего предка – класса ios и потому наследуют его функциональность. Чтобы начать писать программу с использованием ввода/вывода на языке С++, следует обязательно выполнить в программе:

#include <fstream>[3]

Класс fstream предназначен для осуществления чтения и записи в одном конкретном файле и является потомком классов istream и ostream. Эти же классы являются родителями классов ifstream и оfstream.

Классы istream, ostream имеют экземпляры cin, cerr, count, благодаря им осуществляется стандартный ввод/вывод. Ввод осуществляется устройства ввода - клавиатура, а выводится на устройство вывода – экран.

Следовательно, включение в программу класса fstream окажется достаточным для организации файлового и стандартного ввода/вывода.

Для работы с файлом его необходимо открыть – связать с специальной структурой, в которой задаются все необходимые характеристики файла. Данная связь выполняется с помощью функции open. Данная функция входит в классы, отвечающие за ввод/вывод: fstream, istream, ostream.[4]

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

Для записи в файл, необходимо создать экземпляр класса ostream exp и выполнить функцию exp.open()

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

После открытия файла для чтения или записи, экземпляром exp класса ostream можно произвести запись. Для этого необходимо использовать операции включения извлечений (<<). Разберем пример:

exp << "test for C++" << i << j << endl;

Переменные:

i – int i указатель на целочисленное значение;

j - float j указатель на значения с плавающей точкой;

endl – конец ввода и переход на новую строку;

По окончанию работы с файлом его необходимо закрыть. Это разорвёт связь с структурой, с которой был связан файл при открытии. Данная процедура позволит другим файлам открываться. Для закрытия используется метод close(). Для примера, приведенного выше: exp.close().[5]

2. Файловый ввод/вывод с использованием разных классов

Поточные классы – это поставщики инструментов для работы с файлами. В поточных классах хранятся:

  • структуры, обеспечивающие открытие/закрытие файлов;
  • функции (методы) открытия/закрытия файлов;
  • другие функции и данные, обеспечивающие собственно ввод/вывод.

При использовании поточных классов языка С++ в основной программе требуется писать директиву:

using namespace::std;

В противном случае программа не пройдет компиляцию. В исходном коде №1 приводится пример использования директив пространства имен. Результат выполнения данного исходного кода показан на Рисунок 1.

Исходный код №1.

#include <vcl.h>

#include <iostream>

#include <conio.h>

namespace F

{

float x = 190;

}

namespace G

{

using namespace F;

float y = 7.0;

namespace INNER_G

{

float z = 25.01;

}

}

int main()

{

using namespace G;

using namespace G::INNER_G;

float x = 49.4;

std::cout << "x = " << x << std::endl;

std::cout << "y = " << y << std::endl;

std::cout << "z = " << z << std::endl;

getch();

return 0;

}

Рисунок 1.

std::cout – это стандартный вывод. Здесь показано, что объект cout принадлежит пространству имен std.

2.1. Работа с классом fstream

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

Этот класс имеет следующие основные функции (методы):

open() – открывает файл;

close() – закрывает файл;

is_open() – если файл открыт, то возвращает true, иначе — false;

rdbuf() – выдает указатель на буфер ввода/вывода.

Формат функции open(): open(char* file_name, open_mode);

где file_name – имя открываемого файла, open_mode – способ открытия файла. Способ открытия файла задается значением перечислимой переменной: enum open_mode {app, binary, in, out, trunc, ate}; Эта переменная определена в базовом классе ios, поэтому обращение к перечислимым значениям в классе fstream, с экземпляром которого мы работаем, должно идти с указанием класса-родителя: ios::app, ios::binary и т. д.

Назначение способов открытия файла:

app – открыть файл для дозаписи в его конец;

binary – открыть файл в бинарном виде (такие файлы были записаны по определенной структуре данных и поэтому должны читаться по этой же структуре);

in — открыть файл для чтения;

out – открыть файл для записи в его начало. Если файл не существует, он будет создан;

trunc – уничтожить содержимое файла, если файл существует (очистить файл);

ate – установить указатель позиционирования файла на его конец.

При задании режимов открытия файла можно применять оператор логического ИЛИ (|), чтобы составлять необходимое сочетание режимов открытия. Приведем пример программы работы с классом fstream (Исходный код № 2). Результат работы показан на рисунке 2.

Исходный код № 2.

#include <iostream>

#include <conio.h>

#include <fstream>

#include <stdio.h>

int main()

{

using namespace std;

fstream inout;

inout.open("fstream.out", ios_base::in | ios_base::out | ios_base::trunc);

inout << "This is work for Kyrsovaya 1" << endl;

inout << "This is work for Kyrsovaya 2" << endl;

inout << "This is work for Kyrsovaya 3" << endl;

char p[100];

inout.seekg(0);

inout.getline(p, 100);

cout << endl << "String1 :" << endl;

cout << p;

fstream::pos_type pos = inout.tellg();

inout.getline(p, 100);

cout << endl << "String2 :" << endl;

cout << p;

inout.getline(p, 100);

cout << endl << "String3 :" << endl;

cout << p;

inout.seekp(pos);

inout << "This is work for Kyrsovaya 4" << endl;

inout << "This is work for Kyrsovaya 5" << endl;

inout.seekg(0);

cout << endl << endl << inout.rdbuf();

inout.close();

getch();

}

Рисунок 2.

2.2. Работа с классом ofstream

Класс ofstream предназначен для организации работ по выводу (записи) в файл с помощью методов этого класса:

open() – открывает файл для записи в него информации;

is_open() – возвращает true, если файл открыт, и false – в противном случае;

put() – записывает в файл один символ;

write() – записывает в файл заданное число символов;

skeep() – перемещает указатель позиционирования в заданное место файла;

tellp() – выдает текущее значение указателя позиционирования;

close() – закрывает файл;

rdbuf() – выдает указатель на буфер вывода (этот буфер находится в структуре, с которой связывается файл при его открытии).

В исходном коде №3 приведен пример использования класса ofstream.

Исходный код №3.

ofstream FILE;

FILE.open("test.txt");

if(FILE == NULL) return(0);

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

FILE << "string " << i << endl;

FILE.close();

2.3. Работа с классом ifstream

Класс ifstream предназначен для организации работ по вводу (чтению) из файла с помощью методов этого класса:

open() – открывает файл для чтения из него информации;

is_open() – возвращает true, если файл открыт, и false – в противном случае;

get() – читает из файла один символ;

read() – читает из файла заданное число символов;

eof() – возвращает ненулевое значение, когда указатель позиционирования в файле достигает конца файла;

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

seekg() – перемещает указатель позиционирования в заданное место файла;

tellg() – выдает текущее значение указателя позиционирования;

close() – закрывает файл;

rdbuf() – выдает указатель на буфер ввода (этот буфер находится в структуре, с которой связывается файл при его открытии).

Пример использования класса приведен в исходном коде №4.

Исходный код №4.

ifstream FILE;

char p[100];

FILE.open("test.txt");

if(FILE == NULL) return(0);

while(!FILE.eof())

{

FILE >> p;

cout << p << endl;

}

FILE.close();

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

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

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

cout << i;

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

Запишем:

cin >> i >> j >> s;

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

Объект cout

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

Таблица 1.

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

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

Описание

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.45e6

fill(c)

setfill(char_type c)

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

precision(n)

setprecision(int n)

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

setw(int n)

width(n)

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

endl

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

ends

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

flush

flush()

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

ws

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

Пример программы с применением объекта cout приведен в Исходном коде №5. Результат работы представлен на рисунке 3.

Исходный код № 5.

#include <vcl.h>

#include <iostream>

#include <conio.h>

#include <iomanip>

#include <stdio.h>

int main()

{

using namespace std;

int i;

float f;

cout << "Pleace enter i and f >" << endl;

cin >> i >> f;

cout << i << endl;

cout << f << endl;

cout << hex << i << endl;

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

cout << showpos << i << endl;

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

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;

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

cout.precision(6);

cout << f << fixed << endl;

getch();

}

Рисунок 3.

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

Объект (экземпляр класса) cin управляет вводом из буфера ввода, связанного с объектом stdin, объявленным в файле stdio.h. По умолчанию стандартные потоки в языках С и С++ синхронизированы. При вводе используется часть тех функций и манипуляторов, которые определены для cout. Это такие манипуляторы, как dec, hex, oct, ws и др.[7]

Пример программы с использованием объекта cin приведен в Исходном коде №6. Результат работы представлен на рисунке 4.

Исходный код №6.

#include <vcl.h>

#include <iostream>

#include <conio.h>

#include <iomanip>

#include <stdio.h>

void main()

{

using namespace std;

int i;

float f;

char c;

cout << "Please enter i,f,c and then input the string >" << endl;

cin >> i >> f >> c;

cout << i << endl << f << endl << c << endl;

char p[50];

cin >> ws >> p;

cout << p << endl;

cin.seekg(0);

cin.getline(p,50);

cout << p << endl;

getch();

}

Рисунок 4.

Заключение

Специалисты C++ рекомендуют использовать для ввода-вывода только потоки STL и отказаться от использования традиционного ввода-вывода в духе C. Однако, ничего не мешает, по крайней мере пока, использовать традиционную систему ввода-вывода. Более того, предусмотрена специальная функция для синхронизации ввода-вывода, выполненного посредством потоков и посредством старых функций.

Какой механизм использовать – вопрос предпочтений программиста, если работодателем явно непредписанно использование конкретного механизма. В любом случае для физического ввода-вывода используются вызовы операционной системы. Всё остальное – обёртка, набор более или менее удобных функций, или классов для взаимодействия с ОС.

Библиография

  1. Стивен Прата. Язык программирования C++. Лекции и упражнения — М.: Вильямс, 2017. Стр:968.
  2. Стивен Прата. Язык программирования C++. Лекции и упражнения — М.: Вильямс, 2017. Стр:969
  3. Липпман С., Лажойе Ж., Му Б. Язык программирования C++. Базовый курс – Вильямс, 2014. Стр:399
  4. Стивен Прата. Язык программирования C++. Лекции и упражнения — М.: Вильямс, 2017. Стр:973
  5. Мейерс С. Эффективное использование C++. 55 верных советов улучшить структуру и код ваших программ: Пер. с англ. — 3-е изд. — М.: ДМК пресс, 2006.
  6. Стивен Прата. Язык программирования C++. Лекции и упражнения — М.: Вильямс, 2017. Стр:975
  7. Стивен Прата. Язык программирования C++. Лекции и упражнения — М.: Вильямс, 2017. Стр:975