Правила описания перегруженных функций
Перегруженные функции должны находиться в одной области видимости.
Перегруженные функции могут иметь параметры по умолчанию; при этом значения одного и того же параметра в разных функциях должны совпадать. В различных вариантах перегруженных функций может быть различное количество параметров по умолчанию.
Функции не могут быть перегружены, если описание их параметров отличается только модификатором const или использованием ссылки (например, int и const int или int и int &).
Задание
Разработать функцию, вычисляющую максимальный элемент:
- в одномерном числовом массиве, состоящем из целых чисел;
- в одномерном числовом массиве, состоящим из вещественных чисел;
- в массиве строк (для этого массива функция должна находить строку с максимальной длиной).
Функции стандартной библиотеки
Любая программа на С++ содержит обращения к стандартной библиотеке, в которой находятся определения типов, констант, макросов, функций и классов. Для использования их в программе требуется с помощью директивы #include включить в исходный текст программы заголовочные файлы, в которых хранятся соответствующие объявления. Сами библиотечные файлы хранятся в скомпилированном виде и подключаются к программе на этапе компоновки.
Функции библиотеки можно разделить на группы по их назначению: ввод/вывод, обработка строк, математические функции, работа с динамической памятью и т.д.
Функции ввода/вывода
Ввод/вывод в С++ реализуется либо с помощью функций, унаследованных от библиотеки С, либо с помощью потоков С++. Смешивать эти два способа в одной программе можно, только синхронизировав ввод с помощью функции sync_with_stdio ( ).
Для использования функций ввода/вывода в стиле С необходимо подключить к программе заголовочный файл <stdio.h> или <cstdio>. При вводе/вывод данные рассматриваются как поток байтов. Физически поток представляет собой файл или устройство, например клавиатуру или дисплей, рассматривающиеся как частный случай файла.
Открытие потока
Работа с потоком начинается с его открытия. Поток можно открыть для чтения и/или записи в двоичном или текстовом режиме. Функция открытия потока имеет формат:
FILE *fopen(const *filename, cоnst char *mode);
Функция возвращает указатель на предопределенную структуру типа FILE в случае успешного открытия потока, в противном случае − на NULL. Первый параметр функции − путь и имя файла в виде с-строки, второй − режим открытия файла:
"r" − файл открывается только для чтения;
"w" − создается пустой файл для записи (если файл существует, он стирается);
"a" − для добавления информации в конец файла;
"r+" − для чтения и записи (файл должен существовать);
"w+" − открывается пустой файл для чтения и записи;
"a+" − для чтения и добавления информации.
Режим открытия может также содержать символы "t" (текстовый режим) или "b" (двоичный режим).
Пример
FILE *f = fopen("d:\\users\\data.dat", "rb+");
Указатель f используется в дальнейших операциях с потоком. Его передают функциям ввода/вывода в качестве параметра.
Ввод/вывод
Ввод/вывод в поток можно осуществлять разными способами: в виде последовательности байтов, в виде символов и строк или с использованием форматных преобразований. Для каждого вида операций определен свой набор функций.
Операции ввода/вывода выполняются, начиная с текущей позиции потока, определяемой положением указателя потока. Указатель устанавливается при открытии на начало или конец файла (в соответствии с режимом открытия) и изменяется автоматически после каждой операции ввода/вывода. Текущее положение указателя можно получить с помощью функций ftell и fgetpos и задать явным способом с помощью функций fseek и fsetpos:
int fgetpos (FILE *f, fpos_t *pos);
возвращает текущую позицию в файле f и копирует значение по адресу pos. возвращаемое значение имеет тип fpos_t.
int ftell (FILE *f);
возвращает текущую позицию в файле f как длинное целое.
int fseek ( FILE *f, long off, int org);
функция перемещает текущую позицию в файле f на позицию off, отсчитываемую от значения org, которое должно быть одной из трех констант:
SEEK_CUR − от текущей позиции указателя;
SEEK_END − от конца файла;
SEEK_SET − от начала файла.
int fsetpos (FILE *f, const fpos_t *pos);
функция перемещает текущую позицию в файле f на позицию *pos, предварительно полученную с помощью функции fgetpos.
Чтение и запись потока байтов выполняют функции fread и fwrite:
size_t fread (void *buffer, size_t size, size_t count, FILE *stream);
функция возвращает количество прочитанных элементов, которое может быть меньше count, если при чтении произошла ошибка или встретился конец файла.
size_t fwrite (void *p, size_t size, size_t n, FILE *f);
функция записывает n элементов длиной size байт из буфера, заданного указателем p в поток f. Возвращает число записанных элементов.
Чтение символа из потокавыполняют функции getc и fgetc; из стандартного потока stdin − getchar:
int getc (FILE *f);
возвращает очередной символ в форме int из потока f. Если символ не может быть прочитан, возвращается значение EOF (конец файла).
int fgetc (FILE *f);
то же, что и предыдущая функция.
int getchar (void);
возвращает очередной символ в форме int из стандартного ввода. Если символ не может быть прочитан, то возвращается EOF.
Запись символа в поток− putc, fputc; в стандартный поток stdout − putchar.
int putc (int ch, FILE *f);
записывает символ ch в поток f. При ошибке возвращает значение EOF, иначе − записанный символ.
int fputc (int ch, FILE *f);
аналогична предыдущей функции.
int putchar (int ch);
выводит символ ch на стандартное устройство вывода; если вывод успешен, возвращает значение ch, иначе EOF.
Чтение строки из потока− fgets; из стандартного потока stdin − gets:
char * gets (char *s);
считывает символы с клавиатуры до появления символа новой строки и помещает их в строку s. Возвращает указатель на s.
char *fgets (char *s, int n, FILE *f);
читает не более n-1 байт из потока f в строку s, прекращая чтение при обнаружении символа новой строки или конца файла. Символ новой строки не отбрасывается, а помещается в конец строки. Прочитанная строка дополняется ограничителем строки ('\0'). При обнаружении ошибки или конца файла возвращается NULL, в противном случае − указатель на s.
Запись строки в поток− fputs; в стандартный поток stdout − puts.
int fputs (const char *s, FILE *f);
записывает строку символов s в поток f. Символ конца строки не записывается. При ошибке возвращает значение EOF, иначе − неотрицательное число.
int puts (const char *s);
выводит строку s на стандартное устройство вывода, добавляя в конце символ новой строки. Возвращает неотрицательное значение при успехе или EOF − при ошибке.
Форматированный ввод из потока− fscanf; из стандартного потока stdin − scanf, из строки − sscanf.
int fscanf (FILE *f, const char *fmt [, par1, par2, ...]);
вводит строку параметров par1, par2, ...в формате, определенном строкой fmt из файла f. Возвращает число переменных, которым присвоено значение.
int scanf (const char *fmt [, par1, par2, ...]);
вводит строку параметров par1, par2, ...в формате, определенном строкой fmt со стандартного устройства ввода. Возвращает число переменных, которым присвоено значение.
int sscanf (const char *buf, char *format [, par1, par2, ...]);
вводит данные из строки, переданной ей первым параметром; format − строка формата, в соответствии с которым происходит преобразование данных.
Форматированный вывод в поток− fprintf; в стандартный поток stdout − printf; в строку − sprintf.
int fprintf (FILE *f, const char *fmt, ...);
записывает в поток f переменные, список которых обозначен многточием, в формате fmt. Возвращает число записанных символов.
int printf (const char *fmt, ...);
выводит на стандартное устройство вывода значения переменных, указанных в списке, обозначенном многоточием, в соответствии со строкой формата fmt.
int sprintf (char *buffer, const char *format [, argument, ...]);
выводит в строку buffer значения переменных из списка в формате format.
Закрытие потока
Поток закрывается либо при завершении программы, либо явным образом с помощью функции fclose:
int fclose (FILE *);
Обработка ошибок
При работе с файлами используются функции feof и ferror:
int feof (FILE *) − возвращает не равное нулю значение, если достигнут конец файла; в противном случае возвращает нуль.
int ferror(FILE *) − возвращает не равное нулю значение, если обнаружена ошибка ввода/вывода; в противном случае возвращает нуль.
Пример. Программа построчно считывает данные из текстового файла, формирует из них структуру mon и записывает ее в двоичном режиме в выходной файл. В текстовом файле хранятся данные о мониторах. В каждой строке указан тип (20 символов), оптовая и розничная цены (по 5 символов), затем следует примечание длиной не более 40 символов:
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
# include <string.h>
int main ( ) {
FILE *fi, *fo;
if ((fi=fopen("d:\\users\\file.txt", "r")) = =0) {
cout << "Ошибка открытия входного файла"; return 1;}
if ((fo=fopen("d:\\users\\binfile.out", "w+b")) = =0) {
cout << "Ошибка открытия выходного файла"; return 1;}
const int dl=80;
char s[dl];
struct {
char type[20];
int opt, rozn;
char comm[40];
} mon;
int kol =0; // количество записей в файле
while (fgets(s, dl, fi)) {
// преобразование строки s в структуру mon
strncpy (mon.type, s, 19); // копируем первые 20 символов из s в mon.type
mon.type[19]='\0';
mon.opt=atoi(&s[20]); // превращаем строку из пяти символов в целое число
mon.rozn=atoi(&s[25]);
strncpy(mon.comm, &s[30], 40); // копируем в поле комментария оставшиеся
// символы
fwrite(&mon, sizeof mon,1, fo);
kol++;}
fclose (fi);
fclose (fo);
rerurn 0;
}
Задание
Написать программу работы с файлом – телефонным справочником. Предусмотреть выполнение следующих функций:
- просмотр справочника;
- поиск информации по телефону или фамилии;
- добавление новых данных;
- редактирование данных;
- удаление данных;