Константы 5 страница
Преобразование координат используют при изменении масштаба изображения, переносе и повороте изображений. Рассмотрим линейные преобразования координат двумерных объектов. Такие преобразования выполняются с помощью соответствующих формул.
Предположим, что в декартовой системе координат задана плоская геометрическая фигура и — координаты одной из её точек. Пусть координаты этой же точки после преобразования. Тогда параллельное перемещение фигуры на пикселей вдоль оси 0x и на пикселей вдоль оси 0y можно выполнить с помощью формул:
;
.
Растяжение фигуры в и раз выполняется на основе соотношений
;
.
Поворот фигуры вокруг начала координат на угол :
;
.
В ходе разработки анимационных программ необходимо создавать эффект перемещения графических объектов. Простейший способ реализации этого эффекта заключается в том, чтобы нарисовать объект соответствующим цветом, а затем скрыть его путем повторного перерисовывания цветом фона. Затем изобразить объект в новых координатах. С целью повышения быстродействия программы при обработке изображений больших размеров их сначала копируют в оперативную память, а затем выводят на экран их копии в требуемых координатах. Для этого используют функции
void getimage (int x1, int y1, int x2, int y2, void far *bitmap) ;
void putimage (int x, int y, void far *bitmap, int op).
Функция getimage сохраняет в памяти изображение, очерченное прямоугольником, левым верхним углом которого является точка (x1 , y1), а правым нижним — точка (x2 , y2). Изображение сохраняется в памяти по указателю bitmap. Объём памяти, необходимый для хранения изображения, можно определить с помощью функции
imagesize (int x1, int y1, int x2, int y2) ;
Возвращаемое ею значение можно непосредственно передавать одной из функций для выделения оперативной памяти.
Функция putimage восстанавливает изображение на экране в координатах левого верхнего угла (x , y). Параметр op, принимающий возможные значения от 0 до 4, обозначает способ взаимодействия новой копии изображения с изображением, которое уже имеется на экране. В простейшем случае, когда op=0, происходит простое копирование изображения из памяти. Значение op=1 позволяет выполнять побитовую операцию «исключающего или» над содержимым оперативной памяти и видеобуфера для каждого пикселя. Это дает возможность удалить изображение в тех точках экрана, где помещен его оригинал. Если эту операцию выполнить дважды для одних и тех же координат экрана, то изображение не изменится. Это весьма полезно при программировании движущихся по экрану объектов.
Для того, чтобы движущийся по экрану объект отображался в каждой позиции определенное заданное время необходимо предусмотреть приостановление выполнения программы после вывода объекта на экран. Выполнить приостановку программы можно с помощью следующей функции
delay (unsigned int milliseconds) ;
Функция delay приостанавливает выполнение программы на время, определяемое переменной milliseconds, заданное в миллисекундах. Для использования функции delay необходимо подключить библиотеку <dos.h>.
6. Операции над строками и файлами в языке С/С++
6.1. Функции ввода и вывод
Функции ввода и вывода содержатся в библиотеках, как показано на рис. 6.1.
Рисунок 6.1 — Функции ввода и вывода в языках С и С++
6.1.1. Ввод и вывод средствами С
6.1.1.1. Функция getchar()
Формат функции:
int getchar(void) ;
Функция возвращает (передаёт, считывает) в программу символ в форме int из стандартного ввода (клавиатуры). Если символ не может быть прочитан, то функция возвращает значение 0x E0F.
6.1.1.2. Функция putchar()
Формат функции:
int putchar(int ch) ;
Функция выводит на стандартное устройство вывода (на экран монитора) символ ch. Если вывод символа был успешным, то функция передает в программу значение ch, в противном случае возвращается 0x E0F.
Пример:
#include <stdio.h>
void main
{ /* ====== Объявление переменных ====== */
int a; // – считываемый / передаваемый символ
/*====== Начало выполнения программы ====== */
a=getchar( ) ; // – считывание символа с клавиатуры
putchar (a) ; // – вывод символа на экран
/*====== Завершение программы ====== */
return ;
}
6.1.1.3. Функция gets()
Формат:
char *gets(char *s) ;
Функция читает символы с клавиатуры до появления символа новой строки и помещает их в строку s (сам символ новой строки в S не включается). Функция возвращает в программу (передает в программу) указатель на s.
6.1.1.4. Функция puts()
Формат:
int puts(char *s) ;
Функция выводит строку s на стандартное устройство вывода (экран монитора), добавляя в конце символ новой строки. При удачном выводе функция возвращает неотрицательное значение, при ошибке — 0x E0F.
6.1.1.5. Функции printf() и scanf()
Формат:
int printf (const char [[format]…] [, arg 1, …] ) ;
Функция printf выводит на стандартное устройство вывода значения переменных arg 1, … в формате, определённом строкой format.
Формат:
int scanf (const char [ [format]… ] [, arg1 , …] ) ;
Функция scanf вводит строку аргументов (переменных) arg1 , … и т.д. в формате, определённом строкой format, со стандартного устройства ввода. Функция возвращает число, равное количеству аргументов (переменных), которым присвоено значение.
Рассмотрим спецификации формата функций printf() и scanf() и модификаторы:
%[флаг] [ширина] [.точность] [h | l | L] символ_формата ;
Здесь:
[флаг] — задает выравнивание и наличие знака числа:
‘–’ — выравнивание числа по левому краю поля вывода;
‘+’ — печатать числа всегда со знаком;
‘пробел’ — если первая литера не является знаком, что числу должен предшествовать пробел;
[ширина] — задает минимальное количество позиций, отводимых под выводимое/вводимое значение;
[точность] — задает количество позиций, отводимых под дробную часть числа;
[модификатор] — задает спецификатор типа аргумента:
‘h’ — аргумент выводится/вводится как short или unsigned short;
‘l’ — аргумент выводится/вводится как long или unsigned long;
‘L’ — аргумент выводится/вводится как long double;
[символ_формата] — задает тип выводимого/считываемого объекта:
‘с’ — (char)единичная литера;
‘s’ — (char *)строка;
‘d’, ‘i’ — (int)знаковая десятичная запись;
‘o’ — (int) беззнаковая восьмеричная запись;
‘U’ — (int)беззнаковое десятичное целое;
‘X’, ‘x’ — (int) беззнаковая шестнадцатеричная запись;
‘f’ — (double)вещест-е число с фиксирован-й точкой;
‘E’, ‘e’ — (double)вещест-е число с плавающей точкой;
‘G’, ‘g’ — (double)вещест-е число в виде %f или %е
в зависимости от значения;
‘P’ — (void *)указатель (только для printf());
‘%’ — знак процента ‘%’ (только для printf());
Пример:
char *city = ''Sevastopol'' ;
double temp = 18.4 ;
printf(''Atmospheric temperature in %s is %6.2f C. \n'' , city, temp) ;
Результат на экране монитора:
Atmospheric temperature in Sevastopol is 18.40 C.
6.1.2. Ввод и вывод средствами С++
В С++ ввод и вывод осуществляются с помощью потоков.
Поток — абстрактное понятие, обозначающее перенос данных от источника к приёмнику.
Чтение из потока называют извлечением из потока: >> (для входных потоков).
Вывод в поток называют помещением в поток: << (для выходных потоков).
Базовым классом потоков ввода и вывода является класс ios, описанный в заголовочном файле <ios.h>.
Потоковые объекты ввода/вывода (форматируемые):
сin — связывается с клавиатурой (входные потоки с буфером);
сout — связывается с экраном (выходные потоки с буфером);
cerr — связывается с экраном для вывода сообщений об ошибках (выходные потоки без буфера);
clog — связывается с экраном для вывода сообщений об ошибках (выходные потоки с буфером).
Функции (методы) ввода/вывода (неформатируемые):
get () — возвращает считанный из потока код символа или код ошибки 0x E0F;
get (ch) — возвращает ссылку на поток, из которого выполнялось чтение, и записывает извлеченный символ в ‘ch’.
put (ch) — выводит в поток символ ‘ch’ и возвращает ссылку на поток.
Способы форматирования данных в потоковых классах:
— с помощью флагов;
— с помощью манипуляторов;
— с помощью форматирующих методов.
Флаги — отдельные биты, объединённые в поле x_flays типа long класса ios.
6.1.2.1 Форматирование данных с помощью флагов и методов
Поля класса ios, используемые при форматировании:
int x_flags — отдельные биты форматирования, объединенные в поле типа long;
int x_width — минимальная ширина поля вывода;
int x_precision — кол-во цифр в дробной части при выводе вещественных чисел с фиксированной точкой или общее ко-во значащих цифр при выводе в форме с мантиссой и порядком;
int x_fill — символ заполнения поля вывода.
Флаги форматирования данных в потоковых классах представлены в таблице 6.1.
Таблица 6.1 — Флаги форматирования данных в потоковых классах
Флаг | Положение | Действие при установке бита (флага) |
skipws | 0x001 | При извлечении пробельные символы игнорируются |
left | 0x002 | Выравнивание по левому краю поля |
right | 0x004 | Выравнивание по правому краю поля |
internal | 0x008 | Выводится знак числа по левому краю, число — по правому. Между — символы из x_fill (пробелы по умолчанию) |
dec | 0x0010 | Десятичная система счисления |
oct | 0x0020 | Восьмеричная система счисления |
hex | 0x0040 | Шестнадцатеричная система счисления |
showbase | 0x0080 | Выводится основание системы счисления (0x — для шестнадцатеричных чисел, 0 — для восьмеричных) |
showpoint | 0x0100 | Печатать десятичную точку и дробную часть |
uppercase | 0x0200 | При выводе используются символы верхнего регистра |
showpos | 0x0400 | Печатать знак при выводе положительных чисел |
scientific | 0x0800 | Печатать вещественные числа в форме мантиссы с порядком |
fixed | 0x1000 | Печатать вещественные числа в форме с фиксированной точкой (точность — из x_precision) |
Управление флагами поля x_flags c помощью методов flags, setf и unsetf:
long ios :: flags( ) — возвращает текущие флаги потока;
long ios :: flags(long) — присваивает флагам значение параметра;
long ios :: setf(long, long) — присваивает флагам, биты которых установлены в первом параметре, значение битов второго параметра;
long ios :: setf(long) — устанавливает флаги, биты которых установлены в параметре;
long ios :: unsetf(long) — сбрасывает флаги, биты которых установлены в параметре.
Примечание:
— все функции (методы) возвращают прежние значения флагов;
— перед установкой некоторых флагов требуется сбросить флаги, которые не могут быть установлены одновременно с ними. Для этого используют второй параметр метода setf статические константы класса ios:
adjustfiled (left | right | internal) — выравнивание;
basefiled (dec | oct | hex) — система счисления;
floatfiled (scientific | fixed) — представление дробных чисел.
Управление полями x_width, x_precision и x_fill с помощью методов width, precision и fill:
int ios :: width( ) — возвращает значение ширины поля вывода;
int ios :: width(int) — устанавливает ширину поля вывода в соответствии со значением параметра;
int ios :: precision( ) — возвращает значение точности представления при выводе вещественных чисел;
int ios :: precision(int) — устанавливает значение точности представления при выводе вещественных чисел;
char fill( ) — возвращает текущий символ заполнения;
char fill(char) — устанавливает значение текущего символа заполнения.
Пример (форматированный вывод):
…
cout.width(10);
cout.precision(3) , cout.setf(ios :: showpoint) ;
cout.setf(ios :: left , ios :: adjustfield) ;
cout.setf(ios :: fixed , ios :: floatfield) ;
cout<<a ;
…
cout.width(7) ;
cout.setf(ios :: hex | ios :: showbase | ios :: uppercase) ;
cout<<b ;
Пример (неформатированный ввод/вывод):
#include <iostream.h>
void main()
{
int const n=4 ;
int i;
char b[n] ;
for(i=0; i<n; i++)
{ cin.get(b[i]) ; } //<– –b[i]=cin.get();
for(i=n–1; i>=0; i––)
{ cout.put(b[i]) ; }
}
Результат выполнения программы:
Ввод: abcd <ENTER>
На экране: abcd
dcba
6.1.2.2. Форматирование данных с помощью манипуляторов
Манипуляторы — это функции, которые включаются в цепочку операций помещения и извлечения для форматирования данных.
Манипуляторы разделяются на:
— простые (без аргументов);
— параметризированные (требующие указания аргументов).
Особенности использования манипуляторов:
— использование манипуляторов требует подключения библиотечного файла <iomanip.h> ;
— изменение системы счисления действует до следующего явного изменения системы счисления;
— применение манипуляторов удобнее методов установки флагов форматирования.
Рассмотрим простые манипуляторы:
dec — устанавливает при вводе и выводе флаг десятичной системы счисления;
oct — устанавливает при вводе и выводе флаг восьмеричной системы счисления;
hex — устанавливает при вводе и выводе флаг шестнадцатеричной системы счисления;
ws — устанавливает при вводе извлечение пробельных символов;
endl — при выводе включает в поток символ новой строки и выгружает буфер;
ends — при выводе включает в поток нулевой символ;
flush — при выводе выгружает буфер.
Пример:
cout<<13<<hex<<' '<<13<<oct<<' '<<13<<endl;
На экране появится надпись:
13 d 15
Рассмотрим параметризированные манипуляторы <iomanip.h>:
setbase(int n) — задаёт основание системы счисления (n=8, 16, 10 или 0);
resetiosflags(long) — сбрасывает флаги состояния потока;
setiosflags(long) — устанавливает флаги состояния потока;
setfill(int) — устанавливает символ-заполнитель;
setprecision(int) — устанавливает точность вещественных чисел;
setw(int) — устанавливает максимальную ширину поля вывода.
Пример:
//параметризованные манипуляторы:
double d[] = {1.234, -12.34567, 123.456789, -1.234,0.00001};
cout <<setfill(‘.’)<<setprecision(4)
<<setiosflags(ios::showpoint | ios::fixed);
for(int i=0; i<5; i++) cout<<setw(12)<<d[i]<<endl ;
Результат выполнения программы (на экране):
......1.2340
..–12.3457
..123.4568
….–1.2340
……0.0000
6.2. Функции файлового ввода и вывода
Функции ввода и вывода содержатся в библиотеках, представленных на рис. 6.2.
Рисунок 6.2 — Функции ввода и вывода в языках С и С++
Примечание:
— файловый ввод и вывод осуществляется с помощью потокового ввода-вывода;
— перед работой с файлом необходимо открыть файловый поток;
— после работы с файлом необходимо закрыть файловый поток.
Файлы могут быть текстовые и бинарные. На рис. 6.3. представлены их основные отличия.
Рисунок 6.3 — Основные особенности текстовых и бинарных файлов
6.2.1. Файловый ввод и вывод средствами С
Формат объявления/открытия файлового потока:
FILE *имя_потока [ = fopen(const char *имя_файла,
const char *режим_открытия)] ;
Здесь:
режим_открытия — задает режим ввода/вывода:
r — файл открывается только для чтения;
w — файл создается только для записи (стирает предыдущий);
a — файл открывается для добавления данных в конец файла, чтение не разрешено;
r+ — существующий файл открывается для чтения и записи;
w+ — создается новый файл для чтения и записи (стирает предыдущий);
a+ — файл открывается для чтения и добавления данных в конец файла; если файл не существует, то он создается;
t — файл создается или открывается как текстовый (по умолчанию);
b — файл создается или открывается как бинарный.
При успешном открытии потока функция возвращает в программу указатель на структуру типа FILE, если поток открыть не удалось, то возвращает указатель на NULL.
Формат закрытия файлового потока:
fclose(*имя_потока) ;
Примечание:
— ввод/вывод в поток осуществляется через буферы;
— размеры буфера можно изменять с помощью функций setbuf и setvbuf;
— перед закрытием потока вся информация из буферов потока выгружается на диск;
— закрывать поток необходимо всегда, иначе возможна потеря данных.
Пример:
FILE *f_p = fopen (“myfile.txt”, “rt”);
…
fclose (f_p) ;
Примечания:
— при открытии файла на чтение/запись с ним связывается структура FILE. Данная структура содержит для каждого открытого файла счетчик положения текущей записи;
— сразу после открытия файла значение счетчика равно нулю;
— каждая операция ввода или вывода вызывает приращение счетчика.
Получить значение счетчика можно с помощью функций:
long int ftell (FILE *имя_потока) ;
long int fgetpos (FILE *имя_потока, *позиция_в_файле) ;
Примечание:
— функция ftell возвращает текущее значение счетчика в потоке;
— функция fgetpos возвращает значение текущей позиции счетчика в файле, который связан с потоком, и копирует значение счетчика по адресу *позиция_в_файле.
Установить значение счетчика можно с помощью функций fseek, fsetpos, fgetpos, rewind, fgetc.
Формат записи функции fseek:
int fseek (FILE *имя_потока, long смещение, int позиция) ;
Функция fseek — помещает текущую позицию в файле (счетчик) на величину ‘смещение’ в байтах относительно положения ‘позиция’:
SEEK_SET (= 0) — начало файла;
SEEK_CUR (= 1) — текущая позиция в файле;
SEEK_END (= 2) — конец файла.
Формат записи функции fsetpos:
int fsetpos (FILE *имя_потока, const позиция) ;
Функция fsetpos — перемещает текущую позицию в файле на позицию ‘позиция’, предварительно полученную с помощью функции fgetpos.
Формат записи функции rewind:
void rewind (FILE *имя_потока) ;
Функция rewind — устанавливает счетчик на начало потока и очищает флаги ошибок в потоке.
Формат функции ввода символа из файлового потока fgetc:
int fgetc (FILE *имя_потока) ;
Примечание:
— функция fgetc считывает символ из файлового потока;
— при удачном считывании символа возвращает в программу код символа;
— если была выполнена попытка прочесть конец файла или произошла ошибка чтения, то в программу передается код 0xE0F.
Формат функции вывода символа в файловый поток fputc:
int fputc (int ch, FILE *имя_потока) ;
Примечание:
— функция fputc записывает символ ch в файловый поток;
— при удачной записи символа возвращает в программу код записанного символа;
— если произошла ошибка записи кода в поток, то в программу передается код 0xE0F.
Формат функции ввода строки символов из файлового потока fgets:
char* fgets (char *s, int N, FILE *имя_потока) ;
Примечание:
— функция fgets считывает не более N–1 байт из файлового потока в строку s;
— прекращает чтение, если встретился символ перехода на новую строку ‘\n’ или конец файла. Символ ‘\n’ не отбрасывается, а помещается в конец строки s. В переменную s добавляется символ конца строки ‘\0’;
— в случае успешного чтения функция передаёт в программу указатель на строку s;
— при ошибке чтения или достижении конца файла в программу передается указатель на NULL.
Формат функции вывода строки символов в файловый поток fputs:
int fputs (const char *s, FILE *имя_потока) ;
Примечание:
— функция fputs записывает строку символов в поток;
— символ конца строки в поток не записывается;
— при ошибке записи в программу возвращается код 0xE0F, в противном случае — неотрицательное число.
Формат функции форматированного ввода из файлового потока fscanf:
int fscanf (FILE *имя_потока, const char *format [, a1, a2, …]) ;
Примечание:
— функция fscanf вводит из файлового потока строку аргументов a1, a2, … в формате, определенном строкой format;
— в программу функция передает количество переменных, которым присвоено значение;
— функция использует те же способы форматирования, что и функция scanf().
Формат функции форматированного вывода в файловый поток fprintf:
int fprintf (FILE *имя_потока, const char *format [, a1, a2, …]) ;
Примечание:
— функция fprintf выводит в файловый поток строку аргументов a1, a2, … в формате, указанном в строке format;
— в программу функция передает количество записанных аргументов;
— функция использует те же способы форматирования, что и функция printf().
Формат функции проверки достижения конца файла feof:
int feof (FILE *имя_потока) ;
Примечание:
— функция feof проверяет достижение конца файла;
— если конец файла не достигнут, то функция возвращает значение ‘0’, иначе — код 0xE0F.
Формат функции блочного ввода из файлового потока fread:
size_t fread (void *buf, size_t size, size_t N, FILE *имя_потока) ;
Примечание:
— функция fread считывает N блоков по size байт в область заданную указателем *buf из файлового потока;
— в программу функция возвращает количество прочитанных блоков, которое может быть меньше, если произошла ошибка или встретился конец файла;
— размер типа size_t указывает в соответствии со считываемым типом данных.
Формат функции блочного вывода в файловый поток fwrite:
size_t fwrite (const void *buf, size_t size, size_t N, FILE *имя_потока) ;
Примечание:
— функция fwrite записывает N блоков по size байт из области заданной указателем *buf в файловый поток;
— в программу функция возвращает количество записанных блоков;
— размер типа size_t указывает в соответствии с записываемым типом данных.
6.2.2. Файловый ввод и вывод с использованием классов языка С++
Формат объявления/открытия файлового потока:
fstream_class *имя_потока ( const char *имя_файла,
int режим_открытия ) ;
Здесь:
fstream_class — задает потоковый класс ввода/вывода:
fstream — потоковый класс для ввода/вывода в файл;
ifstream — потоковый класс для ввода из файла;
ofstream — потоковый класс для вывода в файл.
режим_открытия — задает режим открытия потока:
ios :: in — открыть для чтения;
ios :: out — открыть для записи;
ios :: ate — установить указатель на конец файла;
ios :: app — открыть для добавления данных в конец;
ios :: trunc — если файл существует, то удалить;
ios :: nocreate — если файл не существует, то выдать ошибку;
ios :: noreplace — если файл существует, то выдать ошибку;
ios :: binary — открыть в двоичном режиме.
Пример:
ifstream filein (“text.txt”, ios :: in) ;
ofstream fileout (“data.dat”, ios :: out | ios :: trunc | ios :: binary) ;
Примечания:
— в примере определяются два объекта filein и fileout входных потоков ifstream и выходных потоков ofstream;
— с указанными объектами можно работать также как со стандартными объектами cin и cout, т.е. использовать операции помещения в поток ‘<<’ и извлечения из потока ‘>>’, флаги форматирования, манипуляторы, методы, состояние потоков, использовать функции get и др.
Формат закрытия файлового потока:
имя_потока.close( ) ;
Примечания:
— функция-метод close() закрывает файловый поток;
— при выходе объекта из области видимости или завершении программы файловый поток закрывается автоматически.
Формат функции проверки достижения конца файла:
имя_потока.eof ( ) ;
Примечания:
— функция eof() класса ios проверяет достижение конца файла;
— если конец файла не достигнут, то функция возвращает значение ‘0’.
Произвольный доступ к записям файлов реализуется двумя методами:
имя_потока.seekg (смещение, ios :: аргумент) ;
имя_потока.seekp (смещение, ios :: аргумент) ;
Примечание:
— функция seekg предназначена для входных потоков;
— функция seekp предназначена для выходных потоков;
— обе функции производят смещение позиции чтения/записи на величину ‘смещение’ в байтах относительно позиции обозначенной аргументом ‘аргумент’:
beg — относительно начала файла;
cur — относительно текущей позиции чтения/записи;
end — относительно конца файла.
Получение текущего значения позиции в потоке ввода или вывода (в файле) реализуется следующим образом:
имя_потока.tellg ( ) ;
имя_потока.tellp ( ) ;
Примечания:
— функция tellg предназначена для входных потоков;
— функция tellp предназначена для выходных потоков.
Формат кода при неформатированном вводе из входного потока:
Дата добавления: 2015-10-21; просмотров: 717;