КИТ и Э КБГУ Понедельник, 06.05.2024, 20:52
Приветствую Вас Гость | RSS
Меню сайта

Наш опрос
Оцените мой сайт
Всего ответов: 118

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Ввод-вывод данных в С/С++

1. Форматный ввод-вывод данных в С

2. Ввод-вывод данных в С++

Лабораторная работа 1. Программирование ввода-вывода с использованием функций PRINTF(), SCANF()

1. Функции семейства ...printf-это универсальные функции вывода в С

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

Форматная строка-это символьная строка, содержащая два типа объектов:

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

Каждая спецификация задается в форме

[флаги][ширина][.точность][F|N|h|l]вид_преобразования

Символы, определяющие вид преобразования ...printf

Символ

 Тип аргумента

Формат вывода

d

целый

 целое десятичное со знаком

i

целый

 целое десятичное со знаком

o

целый

целое восьмеричное без знака

u

целый

целое десятичное без знака

x

целый

целое шестнадцатеричное без знака с символами a, b, c, d, e, f

X

целый

 тот же, что и для x, но с символами A, B, C, D, E, F

f

с плавающей точкой

значение в форме [ -] ...dd.dddddd

e

с плавающей точкой

значение в форме [ -] d.dddddd e [ +/-] ddd

g

с плавающей точкой

значение в форме e или f в зависимости от его величины и точности; незначащие нули и десятичная точка печатаются только при необходимости

E

с плавающей точкой

тот же, что и для e, но экспонента обозначается символом E

G

с плавающей точкой

тот же, что и для g, но с символом E для экспоненты

c

символ

 отдельный символ

s

указатель на строку

печатаются символы строки, пока не встретится символ '/0'

%

( нет )

печатается символ %

n

указатель на int

по указанному адресу запоминается количество напечатанных к этому моменту символов

p

указатель

аргумент печатается как указатель

Спецификатор ширины указывает минимальную ширину поля вывода

Значение

Воздействие на формат вывода

n

печатать по крайней мере n символов, если выводимое значение содержит менее n символов, то поле дополняется пробелами;

0n

печатать по крайней мере n символов, дополняя поле слева нулями, если выводимых символов менее n;

*

значение ширины поля является аргументом функции ...printf, предшествующим в списке аргументов выводимому значению

 

Спецификатор точности определяет количество печатаемых символов

Значение         Воздействие на формат вывода

  1. не указано - устанавливается значение точности по умолчанию :
  • 1-для d, i, o, u, x, X,
  • 6-для e, E, f
  • все значащие цифры - для g, G,
  • все символы до первого '\0' - для s
  1. .0 - для e, E, f-подавляется печать десятичной точки
  2. .n          
  • для d, i, o, u, x, X-печатается по крайней мере n символов; если фактическое значение содержит менее n символов, то оно слева дополняется до n символов нулями; если в фактическом значении более n символов, то они печатаются полностью без какого-либо отсечения
  • для e, E, f-печатается n цифр после десятичной точки; перед отбрасыванием лишних разрядов производится округление
  • для g, G-печатается не более n значащих цифр
  • для s-печатается не более n символов

Флаги для ...printf

-             выравнивание результата по левому краю поля и заполнение справа оставшейся части поля пробелами; -если не указан, то выравнивание по правому краю поля и заполнение слева оставшейся части поля пробелами или нулями

+            результат преобразований d, i, e, g, E, Gвсегда печатается с его знаком: плюс ( +) или минус ( -)

пробел             для положительных чисел вместо знака выводится символ пробела

#            предписывает вывод результата преобразования в "альтернативной" форме:

  • для c, s, d, i, u-не оказывает действия
  • для o-вывод 0перед ненулевым результатом
  • для x, X-вывод соответственно 0xили 0Xперед результатом
  • для e, E, f-всегда выводить десятичную точку
  • для g, G-как и для e и E и без подавления незначащих нулей

 

Замечание. Флаги могут указываться в любых комбинациях и в любом порядке. Флаг ( +) имеет больший приоритет, чем флаг "пробел", если они присутствуют одновременно.

Функции семейства ...scanf-универсальные функции ввода в языке Си.

Единицей вводимой и обрабатываемой ими информации является входное поле.

Порядок следования полей, их содержимое и способ обработки полностью определяются форматной строкой.

Форматная строка -это символьная строка, содержащая три типа объектов:

  1. "прозрачные" символы (пробел, символы табуляции и новой строки);
  2. "непрозрачные" символы (любые символы ASCII за исключением "прозрачных" и символа процента %);
  3. спецификации формата (начинаются с символа %).

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

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

Спецификации формата имеют следующую форму :

%[*][ширина][F|N][h|l|L]вид_преобразования

 

*                        признак подавления присваивания (пропуск поля );

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

F|N                    аргумент-адрес есть соответственно far-указатель (F) или near-указатель (N), применяются для "перекрытия" значения, принятого по умолчанию;

h|l                     аргумент-адрес есть указатель на short(h) или long(l) соответственно, используются для "перекрытия" умолчания;

L                       аргумент-адрес есть указатель на long double.

 

Символы, определяющие вид преобразования для ...scanf

Символы

Вводимое значение

Тип аргумента-адреса

d

десятичное целое

int *arg

o

восьмеричное целое

тот же

i

10-е, 8-е или 16-е целое

тот же

u

10-ецелое беззнака

unsigned int*arg

x, X

16-е целое

int*arg

f, e, g, E, G

с плавающей точкой

float*arg

s

символьная строка

char arg[ ]

c

символ

char*arg или char arg[W+1], если задана ширина поля W

%

символ процента

вводится символ процента

n

( нет )

int*arg, значением arg станет число успешно введенных до %n символов

p

16-е 

YYYY:XXXX far*arg или near*arg, используется или XXXX форма, принятая по умолчанию в зависимости от модели памяти.

Для ввода строки можно задавать в квадратных скобках поисковый образ, например, %[0-9A-F+-]s.

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

Наоборот, спецификация %[^abcd]s предписывает вводить любые символы, кроме перечисленных.

Функции ...scanf прекращают свое выполнение в следующих ситуациях:

1. Очередной символ во входном поле не совпадает с очередным "непрозрачным” символом в форматной строке.

2. Прочитан признак конца файла EOF.

3. Исчерпана форматная строка.

Все функции ...scanf возвращают количество присвоенных значений ( без учета пропускаемых полей ) или EOF при чтении конца файла (конца строки для sscanf).

Замечание. Если в обращении к функции ...scanf количество аргументов-адресов больше, чем число спецификаций преобразования, заданных в форматной строке, то лишние аргументы игнорируются.

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

Пример. Ввод даты в форме 23-feb-89 с выделением ее составных частей - числа, месяца и года.

Предшествующие "прозрачные" символы и внутренние символы тире отбрасываются.

scanf(" %d-%s-%d",&day,&month,&year);

2. Ввод-вывод данных в С++

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

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

#include <iostream>

Класс iostream является потомком классов istream и ostream. Эти же классы являются родителями классов ifstream и оfstream.

Классы 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. В записи мы не видим форматов, но при вводе значений этих переменных с клавиатуры (после ввода каждого значения надо нажимать клавишу <Enter>) их форматы будут учтены.

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

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

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

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

 

Таблица 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

 

setbase(int base)

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

fill(c)

 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() — пробел.

Пример 2.

Пример программы с применением объекта cout.

#include <vcl.h>

#include <iostream>

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

#include <conio.h>

void main()

{

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 символов (заполнение начинается от правой границы к левой). */

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();

}

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

Объект (экземпляр класса) cin управляет вводом из буфера ввода, связанного с объектом stdin, объявленным в файле stdio.h.

cin>>переменная;

 По умолчанию стандартные потоки в языках С и С++ синхронизированы. При вводе используется часть тех функций и манипуляторов, которые определены для cout. Это такие манипуляторы, как dec, hex, oct, ws и др.

Пример 3.

Пример программы с использованием объекта cin.

// cin example #1

#include <vcl.h>

#include <fstream>

#include <iostream>

#include <conio.h>

void main()

{

using namespace std;

int i;

float f;

char c;

// ввод целого числа, числа с плавающей точкой и символа с stdin

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

cin >> i >> f >> c;

// вывод i, f и c на stdout

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

// cin example #2

char p[50];

// приказ на удаление из ввода всех пробелов

cin >> ws >> p;

cout << p << endl;

// чтение символов с stdin, пока не будет нажата клавиша <Enter>

// или не будут прочтены 49 символов

cin.seekg(0);

cin.getline(p,50);

// вывод результата на stdout

cout << p << endl;

getch();

}

Ввод/вывод с использованием разных классов

Итак, мы определили, что поточные классы — это поставщики инструментов

для работы с файлами. В поточных классах хранятся:

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

Пространства имен

Многие серьезные приложения состоят из нескольких программных файлов (с исходным текстом программ), которые создаются и обслуживаются отдельными группами программистов. И только после этого все файлы собираются в общий проект. Но как быть с тем фактом, что в таких файлах могут быть одинаково объявлены разные переменные? В С++ это неудобство разрешается с помощью так называемых пространств имен, которые вводятся в каждый текстовый программный файл проекта с помощью директивы:

Namespace <имя_пространства_имен (идентификатор)> 

{ в эти скобки заключается весь программный текст }

Когда идет сборка общего проекта, то в итоговом тексте пишут директиву:

using namespace:: <идентификатор_пространства_имен>;

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

using namespace::std;

В противном случае программа не пройдет компиляцию.

Пример 1.

Использование директив пространства имен.

#include <vcl.h>

#include <iostream>

#include <conio.h>

namespace F

{ float x = 9; }

namespace G

{

using namespace F;                                                                   /* здесь само пространство G использует пространство F, и в нем же объявляется еще одно пространство: INNER_G */

float y = 2.0;

namespace INNER_G

{

float z = 10.01;

}

}                                                                                            // G

int main()

{

using namespace G;                                                             /* эта директива позволяет пользоваться всем, объявленным в пространстве G */

using namespace G::INNER_G;                                            /* эта директива позволяет пользоваться всем, объявленным только в INNER_G */

float x = 19.1;                                                                     /*локальное объявление переопределяет предыдущее */

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

std::cout << "y = " << y << std::endl;                                  // y берется из пространства F

std::cout << "z = " << z << std::endl;                       /* z берется из пространства  INNER_G */

getch();

return 0;

}

В результате на экране появится:

x = 19.1

y = 2

z = 10.01

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

Вход на сайт

Поиск

Календарь
«  Май 2024  »
ПнВтСрЧтПтСбВс
  12345
6789101112
13141516171819
20212223242526
2728293031

Архив записей

Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz

  • Copyright Fatima_Zh © 2024Бесплатный хостинг uCoz