Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Атрибуты







.[-]

4_43 |4_43

4 43


< DIR> cpp 1 354 exe 117 479 ide 27 714


26.08.2002 23: 28 —-

27.08.2002 01: 07 -a-

27.08.2002 01: 06 -a-

27.08.2002 01: 07 -a-


0 из 143 к в 0 из 3 файда[ов) отмечено;


 
 

c: \cpp\part4\HIes>



 

Рис. 4.44. Командная строка в wc

 

 

4.5.7. Неформатированный ввод/вывод

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

Для записи одного байта предназначена функция put, для считывания одного байта — функция get. Прототипы наиболее часто встречающихся мо­дификаций этих функций выглядят следующим образом:

ostream & put (char ch); istream & get(char & ch);

Функция put записывает символ ch в поток, функция get — считывает символ из потока и присваивает его значение переменной ch. Обе функции возвращают поток, что позволяет использовать сцепленный ввод/вывод. Если get встречает в потоке маркер конца файла EOF, она возвращает ссыл­ку на поток, равную нулю. Приведем обращение к get и put в общем виде:

stream.get(ch); stream.put(ch);

где stream — имя потока (объекта).

В качестве аргумента для функции put можно использовать не только символьную переменную, но и непосредственно код символа.

Например, выражение

cout.put(1F').put(70);

дважды выведет на экран букву F. Другая модификация get:

istream & get(char *buf, int num, char delim='\n');

считывает символы в массив buf до тех пор, пока не считано num символов или не встретился символ delim. Сам символ не извлекается из потока и «ждет», следующего сеанса ввода. В конец массива помещается нулевой символ. По умолчанию аргументу delim присвоен символ перехода на новую строку.

Последней модификации get соответствует другая функция ввода getline с прототипом

istream & getline(char *buf, int num, char delim=1\n');

Отличие getline от соответствующего варианта get состоит в том, что раз­делительный символ считывается из потока. Функция gcount с прототипом

int gcount();

возвращает количество символов, считанных последней операцией ввода. Например, выражение

int i=stream.gcount();

присваивает i значение искомого количества символов.

 

Для записи и считывания нескольких двоичных символов предназначе­ны функции write и read с прототипами:

ostream swrite(const unsigned char *buf, int num); istream & read(unsigned char *buf, int num);

где num — количество символов, которые нужно записать или считать, buf — символьная строка, из которой извлекается конкретная информация для записи или в которую помещается считанная информация. При считы­вании по достижении маркера EOF функция read останавливается и в буфер помещается столько символов, сколько их было считано. В общем виде вызов функций write и read имеет форму:

stream.write((char *)& а, sizeof(а)); stream.read((char *)& a, sizeof(a));

где stream — имя потока, & a — указатель на переменную a, (char *) — опе­рация приведения указателя к типу char.

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

stream.write(string, sizeof(string)); stream.read(string, sizeof(string));

Для работы с числами приведение указателя к типу char обязательно. Произвольный доступ в любое место файла для записи и считывания реа­лизуют соответственно функции seekp и seekg с прототипами:

ostream & seekp(streamoff offset, seek_dir origin); istream & seekg(streamoff offset, seek_dir origin);

где streamoff — тип, который может хранить до offset значений (задан в за­головочном файле iostream.h), seek_dir — аргумент, определяющий началь­ную точку отсчета.

Значения представлены в табл. 4.6. Описание seek_dir в компиляторе (в iostream.h) показано на рис. 4.45.

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


:, S^\ В любом случае отсчет производится отдаданнои точки вперед (в сторону yee%s дичения номера байта). / Жй^ШЙ'Щ^- X

Рис. 4.45. Описание seek_dir

 

При выводе информация хранится во внутреннем буфере и только после его заполнения переписывается на диск (или выводится на экран). Вызов функции flush() освобождает буфер немедленно, аналогично манипулятору flush (см. параграф 1.13).

Программы на рис. 4.46а и 4.48а иллюстрируют использование нефор­матированного ввода/вывода символов. Первая программа реализует после­довательный ввод символов с клавиатуры (функция get), запись в файл w (функция put) и вывод на экран. Командой для окончания процесса являет­ся ввод маркера конца файла EOF (ввод с клавиатуры Ctrl+z), который пре­кращает выполнение цикла do/while. Файл w для записи открыт в режиме обращения ios:: trunc, для того чтобы при повторных запусках программы записи не наслаивались. После открытия файла произведена его проверка filetest (см. рис. 4.42).

Очистка буфера памяти производится тремя способами: функцией flush() и манипуляторами flush и endl.

Вид экрана при исполнении программы показан на рис. 4.466. Содержи­мое созданного файла (stream.bag) показано на рис. 4.47.

Результаты исполнения программ после компиляции под Win (Easy Win) и DOS могут несколько отличаться, что и демонстрируют вариан­ты рисунков 4.466 и 4.47.

Вариант Win: при наборе строки на экран не выводится признак конца файла (~Z), но функция gcount его учитывает (рис. 4.466). При записи в файл EOF интерпретируется, как буква я (рис. 4.47).

Вариант DOS: признак конца файла " Z при наборе строки выводится на экран (рис. 4.436'), при записи в файл — никак не отображается (рис. 4.47').

 

//файл PART4\FILES\4_46.cpp

//Рис.4.46а Неформатированный ввод/вывод

#include < fstream.h>

#include " c: \cpp\class\\gr_txt.h" //Рис. 4.9

#include " с: \cpp\class\\filetest.срр" //проверка файла, рис. 4.42 #define name " stream.bag" //имя файла для записи typedef char STRING;

 

main() { STRING str[]=" \пвведено ", strl[]=" символов\п";

char ch; int k=0;

ofstream w (name, ios:: trunc);

filetest(w); //проверка файла

cout< < endl«" BBeflHTe строку\покончание-ввод Ctrl + z" «endl; do{cin.get(ch); //ввод с клавиатуры

w.put(ch); //запись в файл cout.flush ();

cout< < ch; cout.flush(); //вывод на экран, очистка буфера

k++; //количество символов

}while(! cin.eof()); //контроль ввода EOF

cout«str«k< < strl«f lush; pause(9); return 0; }

 

Рис. 4.46a. Неформатированный ввод/вывод. Запись в файл

C: \CPP4PART44FILES\4 46.EXE


 
 

Рис. 4.466. Результат исполнения программы на рис. 4.46а. Вариант Win

 

введите строку окончание-ввод Ctrl+z Ехали медведи на велосипеде. Ехали медведи на велосипеде._ введено 29 символов

3£ айл ~ -QpaeKa Поиск; Jjnpx

 

Ехали медведи на велосипеде.я

 

 

Рис. 4.47. Содержимое файла stream.bag, созданного программой на рис. 4.46а. Вариант Win (Notepad)

 

Ехали медведи на велосипеде.

 

 

Рис. 4.47'. Содержимое файла stream.bag, созданного программой на рис. 4.46а. Вариант DOS (пс)

 

Указанные особенности обсуждаются в Приложении 4.

Запись в файле выглядит, как форматированная, так как символы все­гда выводятся в натуральном виде.

Считывание предыдущей записи из файла осуществляет программа на рис. 4.48а. Результат представлен на рис. 4.486.

 

// Файл PART4\FILES\4_4 8.cpp

// Рис. 4.48а. Считывание из файла

#include < fstream.h>

#include " с: \cpp\ciass\\gr_txt.hV/текст.граф., рис. 4.9 tinclude " c: \cpp\classWfiletest.cpp" //Рис. 4.42 #define name " stream.bag" //имя файла для счит. typedef char STRING;

 

main() {int 1;

STRING poem[4][50], strl[]=" символов\п", str2[]=" Хпсчитано "; ifstream r(name); filetest(r); //проверка /*№1*/ r.getline(poem[0], 49, •.'); l=r.gcount(); cout«str2< < K< strl«flush; cout«poem[0]; cout. flush (); /*№2*/ r.seekg(0, ios:: beg); //позиционирование

r.get(poem[l], 4 9, '.'); //считывание

■ l=r. gcount (); //кол-во символов cout«str2«l«strl«f lush; cout«poem [ 1 ]; cout. flush (); /*№3*/ r.seekg(O); //позиционирование

r.read(poem[2], 9); //считывание

l=r.gcount(); //кол-во символов cout«str2«l«strl«f lush; cout«poem [2]; cout. flush ();

/*№4*/ r.seekg(3, ios:: cur); //позиционирование r.read(poem[3], 8); //считывание l=r.gcount(); //кол-во символов


cout«str2«l«strl«f lush; cout< < poem[3]; pause(9); return 0; }



 

Рис. 4.486. Результат исполнения программы на рис. 4.48а. Вариант Win

 

Файл stream.bag открывается для считывания, режим ios:: in устанавли­вается по умолчанию.

Первоначально (№1) символы считываются с помощью функции getline в строку роет[0]. В качестве ограничителя выбрана точка. Необходимо, во избежание неприятностей, проследить, чтобы среди считываемых символов присутствовал избранный ограничитель. Функция gcount определяет коли­чество считанных символов. Результат приведен на рис. 4.486. Считано 28 символов, но на экран выведено только 27 (без знака-ограничителя).

Вторично (№2) текст считывает функция get и помещает в роега[1], но предварительно функция seekg производит позиционирование в начало файла. Результат считывания тот же, но gcount насчитывает только 27 сим­волов, так как get не считала символ-ограничитель.

Третий этап считывания (№3) также предваряется позиционированием в начало файла (ios:: beg устанавливается по умолчанию). Функция read счи­тывает 9 символов и помещает в роет[2].

На четвертом этапе (№4) производится позиционирование на три байта от текущей позиции, после чего read считывает 8 символов и помещает в роеш[3]. В двух последних вариантах после полезной информации выво­дится остаточное содержимое буфера памяти.

Функции write и read в качестве аргумента воспринимают указатель, поэтому с их помощью можно записать и считать не только базовые перемен­ные. В программе на рис. 4.49а показана программа, в которой записывают­ся и считываются массив чисел типа float, массив строк и структура. Иско­мый файл bag.bag открывается для записи и считывания. Перед записью собственно массивов записываются их размеры в байтах, для того чтобы при считывании задать второй аргумент функции read. Размеры каждого эле­мента структуры записаны в отдельности для вывода результатов считыва­ния на экран, так как специальная функция вывода для объектов структур­ного типа student не разрабатывалась.

После записи произведено позиционирование для считывания в начало файла. Для размещения считанных величин заданы новые переменные.

Результат исполнения программы показан на рис. 4.496, содержимое файла — bag.bag на рис. 4.50.

 

//файл.PART4\FILES\4_4 9.cpp

//Рис. 4.4 9а Запись и считывание массивов и структуры #include < fstream.h>

tinclude " с: \срр\class\\gr_txt.h" //текст.граф., рис.4.9

#include " c: \cpp\classWfiletest.cpp" //Рис.4.42

tdefine name " bag.bag" //имя файла для записи и считывания

 

main () {

//файл открывается для записи и считывания

fstream f(name, ios:: in | ios:: out);

filetest(f); //проверка файла

 

int i, sizel, size2, size3, size4,

sizef=sizeof(float), sizei=sizeof(int);

cout«,, /4 ПОДГОТОВЛЕНО ДЛЯ ЗАПИСИ л\п";

//массив чисел для записи float array[]={16., -22.,.244, 333.51); sizel=sizeof(array); //размер массива чисел в байтах for (i=0; Ksizel/(sizef); i++) cout«array [i] «' '; f.write((char*) & sizel, sizei); //запись размера массива f.write((char*) array, sizel); //запись массива

//массив строк для записи char stringArray[2][10]={" BJARNE ", " STROUSTRUP" }; size2=20; cout«1 \n' «stringArray [ 0 ] «endl;

f.write((char*) & size2, sizei); //запись размера массива f.write((char*) stringArray, size2); //запись массива

//структура для записи struct student{char firstname[10]; char lastname[10];

int mark; float money; }; student ob={" John ", " Smith ", 5, -13.2}; // sizel=sizeof(ob.firstname); //определение размеров size2=sizeof(ob.lastname); //элементов структуры size3=sizeof(ob.mark); size4=sizeof(ob.money);

cout< < ob. f irstname«ob. lastname«ob.mark«' 1 «ob.money«' \n ' «endl;

f.write((char*) & sizel, sizei); //запись размеров

f.write((char*) & size2, sizei); //элементов структуры

f.write((char*) & size3, sizei);

f.write((char*) & size4, sizei);

f.write((char*) & ob, (sizel+size2+size3+size4)); /*запись структуры*/

 

//считывание

float arrayl[10]; char stringArrayl[25]; student obi; int sizell, size21, size31, size41; //переменные для размещения

//счит.величин


f. seekg(0, ios:: beg); //позиционирование в начало файла соиг.«" ЛЛЛЛЛЛ СЧИТАНО ллллллллл\п";

f.read((char*) & sizell, sizei); //считывание размера массива чисел f.read((char*) Sarrayl, sizell); //считывание массива чисел for (i=0; i< sizell/sizef; i++) cout«arrayl [i] «' '; cout«endl;

 

f.read((char*) & size21, sizei); //считывание размера строки

f.read(stringArrayl, size21)///считывание строки

for (i=0; i< size21; i + +) cout«stringArrayl [i]; cout«endl;


f.read((char* f.read((char* f.read((char* f.read((char* f.read((char* f.read((char* f.read((char* f.read((char*

Ssizell, sizei); //считывание размеров & size21, sizei)///структурных элементов & size31, sizei); & size41, sizei);

& obl.firstname, sizell); //считывание & obl.lastname, size21); //структурных & obl.mark, size31); //элементов & obl, (size41+ size31+ size21+ sizell)); f.close(); //файл закрыт

cout«obl. f irstname< < obl. lastname«obl. mark«1 ' < < obl. money; pause(0); return 0; }

 

Рис. 4.49a. Запись и считывание производных переменных

C: \CPP\PART4\FILESV4 4..

ПОДГОТОВЛЕНО ДЛЯ ЗАПИСИ 16 -22 0.244 333.51 BJflRNE STR0USTRUP John Smith 5 -13.2

! ----------- СЧИТАНО

Рис. 4.50. Содержимое файла bag.bag


Нб -22 0.244 333.51 jBJARNE STROUSTRUP John Smith 5 -13.2


Рассмотрим еще одну программу с именем copir, посимвольно копирую­щую содержимое одного файла г в другой w (рис. 4.51а). Программа исполь­зует аргументы командной строки.

 

//файл UTIL\copir.срр

//Рис. 4.51а Копирование из одного файла в другой //Аргументы командной строки tinclude < fstream.h>

#include " c: \cpp\class\gr_txt.h" //Рис. 4.9 #include " c: \cpp\class\filetest.cpp" //Рис.4.42

 

main(int argc, char *argv[ ]) { if(argc! =3)

cout< < " \nnoBTopnTe запуск, но предварительно" < < " \пнаберите в командной строке: " «" \ncopir.exe пробел" < < " \пфайл считывай, пробел" < < " \пфайл записи";

else

{ifstream r(argv[l]); //r-файл для считывания filetest(г); //проверка открытия файла г ofstream w(argv[2], ios:: app); //w-файл для записи filetest(w); //проверка открытия файла w while(! r.eof()) w.put((char)r.get()); cout< < " \псодержимое файла " «argv[l]

«" \пскопировано в файл " < < argv [2] «endl; }; pause (0); return 0; }

 

Рис. 4.51a. Программа copir. Копирование одного файла в другой

Ш C: \CPP\UTIL\COPIR.EXE


|повторите запуск, но предварительно наберите в командной строке: copir.exe пробел |файл считывай, пробел! < раил записи

С: \CPP\U ТI L\COPI R. EXE

Ш


 
 

Рис. 4.516 (кадр 2). Результат исполнения программы на рис. 4.51а. Второй запуск (из командной строки).


C: \CPP4UTIL\C0PIR.EXE


содержимое Файла c: \cpp\part4\files\stream скопировано в Файл new.box


.bag~j


 

Рис. 4.516 (кадр 3). Результат исполнения программы на рис. 4.51а. Третий запуск (из командной строки)

 

При запуске из командной строки создается новый файл для записи, если ранее он не существовал. Так как файл для записи открывается в режи­ме ios:: app (дополнение в конец файла), к нему можно при повторных запус­ках присоединять содержимое других файлов.

Для примера перепишем в новый файл new.box содержимое файла PARTl\FILES\basel.box (рис. 1.53), а после этого присоединим текст файла stream.bag (рис. 4.47). Файл new.box будет создан в директории, куда запи­сан файл copir.exe.

Командная строка показана на рис. 4.52 и 4.53.


e: \epp\part1 \ftIesV


сЛсрр\иШ\\"


тИвЙгя Тип Разме Дата


ТИмя


ТйН Размер 1 Дата


1_52 1_54 1_56 J Basel

ы


 

срр срр срр box

,.[..1 < DIR> 27.07.2001 23: 22 ---^

]Code exe G1 479 27.07.2001 22: 36 -а □ CODEw EXE 130 851 1G.07.2001 09: 40 -as

Г

JCopifЗхё ~^еэ~~27^Ш^Г^Ш^^

3Do*2win exe 13 078 2TS999l7: 2l~-a^

cpp 2 252 ^ 0 из 273 k в 0 из 5 Файяа[ов} отмечено


\с: 4cppVutil> JCQPIR.EXE c: \cpp\part1Vfiles\base1.box new.box ▼ }

 

Рис. 4.52. Командная строка, перед вторым запуском (wc)


с- \cpp\par t4\f iles\*."


c: \cpp\utilW


fИмя ^Тип 1 Разме! Дата i


ТИмя ■ '.•У'; & , Тиг Размер Дата


Tftri


 
 

4_60 срр
4_63 срр
4_GB срр
Sir earn bag

□ CODEw EXE 130 851

QCopir exe 61 869

Fa|Dos2win exe 13 078

New bd£ 052 567

Win2dos exe 13 078
16.07.2001 09: 40 -a 27.07.2001 22: 36 -a-24.02.1999 17: 21 -a-15.08.2001 19.10 -a-24.02.1999 17: 27 -a-v


c: \cpp\util> JCOPIR EXE c: \cpp\pait4\files\stream bag new.box V

 

Рис. 4.53. Командная строка, перед третьим запуском (wc)

 

На рис. 4.54 и 4.55 показано содержимое файла new.box после одно- и дву­кратного запуска copir.exe из командной строки, полученного при компиля­

ции Easy Win, поэтому в тексте видны «лишние» буквы я (см. Приложение 4). Если пресловутая я в новом файле неуместна, можно применить, например, прием, использованный в программе exchange (см. Приложение 5).

 

ff± new.box - Блокнот  
~Ь" '^' -~  
  а
1 иванов 15.4 4  
44 петров -18.2  
5 сидоров 88  
22 чижиков 55.67  
41 дроздов -223. 1  
я  
   

1 иванов 15.44

44 петров -18.2

5 сидоров 88

22 чижиков 55.67

41 дроздов -223.1

яЕхали медведи на велосипеде.яя

 

 

Рис. 4.55. Содержимое файла new.box после присоединения (Notepad)

 

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

Имя программы copir дано для того, чтобы отличать ее от известной про­граммы сору аналогичного назначения в DOS. Для сравнения пример ко­мандной строки сору показан на рис. 4.56. Если file.rez не указан, сумма по­мещается в file.txt 1.

 

Щcopy filel Лxt * file2.txt ♦ file3.txt file.rez Щ

 

Рис. 4.56. Командная строка (wc) для функции OS DOS copy

4.6. Пример работы с файлами. База ланных

 

Базой данных обычно называют группу связанных файлов. Совокуп­ность программ, предназначенных для создания баз данных и управления ими, называется системой управления базой данных (СУБД).

Рассмотрим СУБД для учета банковских клиентов. Так как предлагае­мый комплект программ составлен для демонстрации приемов программи­рования, но не для практического использования, в них не предусмотрена обработка всех возможных ситуаций, что обязательно для качественных пользовательских программ. При разработке реальной пользовательской программы следует также более внимательно отнестись к интерфейсу с точ­ки зрения его удобства и привлекательности. Читатель имеет возможность сравнить уровень программирования и возможности развития этой системы со сходными по назначению программами в параграфе 1.14.

4.6.1. Предварительные условия

Сформируем некоторые исходные условия для построения нашей СУБД:

■ Данные о клиентах записываются в файлы-списки на N персон каждый;

■ Данные об имеющихся файлах-списках хранятся в отдельном управ­ляющем файле;

■ При работе с файлами-списками осуществляется форматированный

ввод/вывод с последовательным доступом;

■ Управляющий файл выполняется как файл с неформатированным вводом/выводом и произвольным доступом;

■ Манипуляции с данными о клиенте производятся после считывания содержимого файла-списка в массив. По окончании работы записыва­ется новый вариант файла-списка.

■ Записи (перезаписи) в файлы-списки осуществляются после предъяв­ления пароля.

4.6.2. Программное обеспечение

Все данные и функции, необходимые для составления частных про­грамм СУБД, размещены в наборе классов Cntr, Client, Sort и File, объеди­ненных по схеме рис. 4.57.

Cntr — работает с управляющим файлом,

Client — содержит элементы данных о клиенте,

Sort — наследует классу Client, содержит функции, манипулирующие данными о клиенте,

File — наследует классу Sort, содержит функции для работы с файла­ми-списками.


 

Client

 

Sort


File


ob г —►

Cntr


 

Рис. 4.57. Схема программного обеспечения СУБД

 

Для объединения цепочки классов Client 4r Sort File с классом Cntr в класс File введен открытый элемент — объект типа Cntr.

 

 

4.6.3. Класс Cntr

Класс Cntr предназначен для обеспечения операций создания и регист­рации новых файлов-списков, исключения имеющихся файлов-списков, контроля текущего набора файлов-списков. Объявление и описание класса помещены в директорию CLASS, файлы cntr.h и cntr.cpp соответственно (рис. 4.58, 4.59).

 

// Файл CLASS\cntr.h

// Рис. 4.58. Класс Cntr, управляющий списком файлов #ifndef CNTR #define CNTR #include < string.h>

#include " c: \cpp\subprog\\roll.h" //Рис. 1.26 #include " c: \cpp\classWgr_txt.h" //Рис. 4. 9 #include < fstream.h>

#include " c: \cpp\class\filetest.cpp" //Рис.4.42 typedef char STRING;

 

class Cntr { int k; protected:

STRING cntr[9]; //имя управляющего файла public:

Cntr(){k=sizeof(k); } -Cntr () { }

STRING box[9]; //шаблон имени рабочего файла

void init(); //инициализация файлов

void newfile(); //новый упр. файл, разметка

void correct(); //корректировка данных

void report(); //состояние файловой системы

};

#include " c: \cpp\class\cntr.cpp" //Рис. 4.59 #endif

 

Рис. 4.58. Объявление класса Cntr

//файл CLASS\cntr.cpp

//Рис. 4.59 Класс Cntr, управляющий списком файлов //описание функций void Cntr:: init() {

cout«" \n ввод имени управл. файла без расшир., "

«" \n не более 4 символов "; cin»cntr; strcat (cntr, ".box"); //добавление расширения

strcpy(box, " box.box"); /*инициализация шаблона*/} void Cntr:: newf ile () { init();

cout«" \n ЕСЛИ ФАЙЛ С ЭТИМ ИМЕНЕМ СУЩЕСТВУЕТ, "

«" \n ОН НЕ БУДЕТ ОТКРЫТ\п"; ofstream ob(cntr, ios:: noreplace); //файл открыт //для записи, если он ранее не существовал filetest (ob); //проверка файла cout< < " \n\n управл.файл с именем " «cntr; cout< < " \n обслуживает 9 файлов-списков";

int number=0, с=49; //49 - код символа 1(см. Приложение 4) for (int i=l; i< =9; i++)

{ob.write((char*)Snumber, k); //запись нуля и

box[3]=(char)С++; ob.write(box, 9); }; //имени файла-списка ob.close(); //файл закрыт cout< < " \n конец разметки"; }

 

void Cntr:: report(){

ifstream ob(cntr); //файл открыт для считывания filetest (ob); //проверка файла int number, i=0, j=0;

cout«" \n зарегистрированные списки: "; while(i< 9){

ob.read((char*)Snumber, k); ob.read(box, 9);

if (number! =0) {cout«" \n " «number«' '«box; j++; }; i++; }; if (j==0) cout«" \n нет зарегистр. списков"; cout< < flush;

ob^close(); /* файл закрыт*/; pause(9); } void Cntr:: correct (){

fstream ob(cntr, ios:: in I ios:: out); //откр.файла для записи

//и считывания

filetest (ob); //проверка файла

cout«" \n\n КОРРЕКТИРОВКА УПРАВЛ. ФАЙЛА";

cout«" \n ввод № списка (от 1 до 9) "

< < " \п отмена корректировки: ввод 0(ноль) "; int i, number; cin> > i; while(i! =0){ if(i> 0 & & i< 10)

{ob.seekg((k+9)*(i-1)); //позиционирование для считывания ob.read((char*)Snumber, k); /*считывание №*/} else number=10;

 

switch (number) //варианты корректировки {case 0:

{cout< < " \nHOMep списка свободен, идет регистрац."; ob.seekp((k+9)*(i-1)); //позиционирование для записи ob.write((char*)& i, k); /*запись*/

box[3]=(char)(48+i); //48-код ноля ofstream obf(box); filetest(obf); obf.close()///создание файла-списка }break;

case 1: {}; case 2: {}; case 3: {}; case 4: {}; case 5: {}; case 6: {}; case 7: {}; case 8: {}; case 9: {cout«" \n список № " < < number «" существует, " < < " \n исключение: ввод 0(ноль)" «" \n отмена: нажать любую клавишу "; char l; cin> > l; int il=l;

if (, 0, ==1) {cout«" CnMCOK ИСКЛЮЧАЕТСЯ"; i-l=0;

ob.seekp((k+9)*(i-1)); //позиционирование для записи

ob.write((char*)& il, k); //запись нуля

box[3]=(char)(48+i); //48-код нуля

ofstream obf(box, ios:: trunc);

filetest(obf);

obf.close(); /*стирание содержимого файла-списка*/} else cout«" \n ИСКЛЮЧЕНИЕ ОТМЕНЕНО"; }break; default:

cout: < < " \n введен ошибочный номер, повторите"; }; //конец переключателя

cout< < " \n\n введите № списка(от 1 до 9) " < < " \п окончание: ввод 0(ноль) ";

cin> > i; }; //конец while ob.close(); /*файл закрыт*/ cout< < " \n КОРРЕКТИРОВКА ОКОНЧЕНА"; pause(9); report(); }

 

Рис. 4.59. Описание функиий класса Cntr

 

Класс Cntr содержит данные: строки для имени самого управляющего файла (cntr[9]), и для имени файла-списка (Ьох[9]) и функции:

■ init — для инициализации имен файлов. Имя управляющего файла вводится с клавиатуры без расширения, которое добавляется автома­тически. Инициализируется шаблон для имени файла-списка с пробе­лом для номера (элемента строки box с индексом 3).

■ newfile — для создания нового управляющего файла. После вызова функции init открывается управляющий файл cntr в режиме записи, но только в том случае, если он ранее не существовал. После проверки filetest (рис. 4.42) производится разметка файла произвольного досту­па для регистрации 9 файлов-списков. В каждую ячейку (аналогично рис. 1.55) записывается ноль вместо номера файла и шаблон имени со вставленным символом, совпадающим по написанию с номером фай­ла-списка. Например, 0box4.box — заготовка для регистрации фай­ла-списка номер 4 с именем Ьох4.Ьох. После разметки управляющий файл закрывается. Количество байтов для записи типа int (ноля) опре­деляется автоматически в конструкторе класса Cntr.

■ correct — для создания новых файлов-списков и исключения имею­щихся. Управляющий файл открывается для записи и считывания.

Номер искомого файла-списка i вводится с клавиатуры. Если введено разрешенное число, производится считывание с позиций, соответст­вующих номеру файла. Далее переключатель выбирает вариант дей­ствия. Если номер свободен (считан ноль), на это место записывается введенное число. Для того чтобы реально создать файл, он открывает­ся для записи и после проверки закрывается. Если номер занят (счита­но число от 1 до 9), можно отменить корректировку управляющего файла или исключить файл-список с этим номером. Для исключения на место номера записывается ноль, файл открывается в режиме запи­си со стиранием его содержимого, после чего закрывается. (Эта опера­ция, конечно, физически не удаляет файл из компьютера.) Если слу­чайно введен неразрешенный номер списка, предлагается повторить ввод. После окончания корректировки функция report производит проверку содержимого управляющего файла. ■ report — для контроля состояния файловой системы. Управляющий файл открывается в режиме считывания, на экран выводятся номера и имена зарегистрированных файлов, после чего файл закрывается.

Программа, создающая и корректирующая управляющий файл, пока­зана на рис. 4.60а. Результат исполнения программы приведен на рис. 4.606 (пять кадров).

 

//файл PART4\FILES\4_60.cpp

//Рис.4.60а Управление файловой системой

#include " c: \cpp\classWcntr.h" //Рис.4.58

 

main () {

cout«" \n\n УПРАВЛЕНИЕ ФАЙЛОВОЙ СИСТЕМОЙ"; Cntr ob; //объект типа Cntr ob.newfile(); //новый управляющий файл ob.report(); pause(0); //отчет ob.correct(); //корректировка с отчетом pause(9); return 0; }

 

Рис. 4.60а. Программа управления файловой системой

Ш C: \CPP\PART4\FILES\4_60.EXE


 

УПРАВЛЕНИЕ ФАЙЛОВОЙ СИСТЕМОЙ ввод имени управл. Файла без расшир.,

не более 4 символов Ьоха

ЕСЛИ ФАЙЛ С ЭТИИ ИМЕНЕМ СУЩЕСТВУЕТ, ОН НЕ БУДЕТ ОТКРЫТ error file

ESC - выход в ОС, др.клавиша - продолжение работы


C: \CPP\PART4\FILES\4 БО.ЕХЕ

 

УПРАВЛЕНИЕ ФАЙЛОВОЙ СИСТЕМОЙ ввод имени управл. файла без расшир., не более Ц символов ЬохО

ЕСЛИ ФАЙЛ С ЭТИМ ИМЕНЕМ СУЩЕСТВУЕТ, ОН НЕ БУДЕТ ОТКРЫТ

 

управл.Файл с именем ЬохО.box обслуживает 9 Файлов-списков конец разметки зарегистрированные списки: нет зарегистр.списков.

 

 

Рис. 4.606 (кадр 2). Результат исполнения программы на рис. 4.60а. Повторный запуск

Ш C: \CPP4PART4\FILES\4_B0.EXE

 

КОРРЕКТИРОВКА УПРАВЛ. ФАЙЛА ввод № списка(от 1 до 9) отмена корректировки: ввод О(ноль) 7

номер списка свободен, идет регистрац.

введите № списка(от 1 до 9) окончание: ввод О(ноль) Ц

номер списка свободен, идет регистрац.

введите К списка(от 1 до 9) окончание: ввод О(ноль) 7

список К 7 существует, исключение: ввод О(ноль) отмена: нажать любую клавишу О СПИСОК ИСКЛЮЧАЕТСЯ

 

Рис. 4.606 (кадр 3). Результат исполнения программы на рис. 4.60а

Кадр 1: попытка создать (открыть) уже существовавший файл boxa.box. Срабатывает запрет в функции newfile.

Кадр 2: создание управляющего файла ЬохО.Ьох и его разметка. Отраба­тывают функции newfile и report. Корректировка отменена вводом ноля.

Кадры 3, 4, 5: перебор различных вариантов корректировки. Общий ре­зультат — регистрация файлов-списков номер 4 (Ьох4.Ьох) и номер 9 (ЬохЭ.Ьох).


 
 

В C: \CPP\PART4\F1LES\4 БО.ЕХЕ

| введите № списка(от 1 до 9)

; окончание: ввод О(ноль) 4

| список Н Н существует,

: исключение: ввод О(ноль)

| отмена: нажать любую клавишу s

!

| ИСКЛЮЧЕНИЕ ОТМЕНЕНО

I

: введите № списка(от 1 до 9)

! окончание: ввод О(ноль) 9

i i

Ыомер списка свободен, идет регистрац.

| введите № списка(от 1 до 9)

j окончание: ввод О(ноль) 14

введен ошибочный номер.повторите


 


 

 

Рис. 4.606 (кадр 4). Результат исполнения программы на рис. 4.60а

C: \CPP\PART4\FILES\4 БО.ЕХЕ


 
 

введите К списка(от 1 до 9) окончание: ввод О(ноль) О

КОРРЕКТИРОВКА ОКОНЧЕНА зарегистирированные списки:

4 DOX4.D0X j 9 Ьох9.Ьох_


Рис. 4.606 (кадр 5). Результат исполнения программы на рис. 4.60а


На рис. 4.61 показано содержимое части управляющего файла ЬохО.Ьох с зарегистрированным списком № 4 Символы читабельны, а число 4 (номер файла-списка) показано условным значком (в данном случае _).

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

Файл, управляющий файловой системой, а также файлы, созданные в результате исполнения программы, рекомендуется размещать в одной и той же специальной директории, например, PART4\FILES.

4.6.4. Классы Client, Sort и File

Классы Cient, Sort и File соединены в цепочку (рис. 4.57) и содержат данные и функции, обеспечивающие работу с файлами-списками, в которых хранятся сведения о клиентах банка. Объявления и описания классов поме­щены в директорию CLASS, файлы bank.h и bank.cpp соответственно.

Класс Cient и структура client (см. рис. 4.62 и 4.63) содержат уже знако­мые элементы для записи сведений о клиенте. Размер массива структурных объектов m[N] задается директивой #define и ограничивает количество кли­ентов в списке (для демонстрационной задачи достаточно 10). При активиза­ции конструктора класса Cient инициализируется счетчик реального коли­чества клиентов в списке К=0.

Класс Sort (см. рис. 4.62 и 4.63) содержит функции для обработки дан­ных о клиенте в массиве:

■ swop и sort идентичны ранее использовавшимся.

■ sortl несколько модернизирована. В предыдущем варианте (рис. 4.6) выход ранее 10 попыток осуществлялся клавишей Esc через посредст­во функции pause. Это было удобно, так как sortl всегда использова­лась в конце программы и возвращение в операционную систему было уместно. В ныне представленном варианте для выхода введен допол­нительный индекс 0 (ноль).

■ Для вывода массива на экран вызывается специальная функция-эле­мент того же класса screen, которая выводит на экран заполненные элементы массива. Условие исключения клиента из списка — при­сваивание ему нулевого номера, то есть m[i].number =0. В данном слу­чае условие вывода данных — неравенство нулю номера клиента — из­быточно, так как заполнение массива контролируется параметром К.

■ search производит поиск в массиве при его текущем состоянии свобод­ного номера для нового клиента. Используется глобальная целая пере­менная num, что позволяет расширить возможности применения по­лученного номера. В результате выдается сообщение о свободном но­мере или о том, что список заполнен.

.■ searchl производит поиск клиента в массиве по его номеру. Если но­мер найден, сведения о клиенте выводятся на экран. Если номер свобо­ден, выводится соответствующее сообщение. Если номер повторяется, выводится сообщение об ошибке. Индекс элемента массива (не путать с номером клиента), в котором записаны данные о последнем из най­денных клиентов, сохраняется в глобальной переменной п.

■ search2 производит поиск клиента в массиве по имени. На экран выво­дятся сведения обо всех однофамильцах. Индекс элемента массива, в котором записаны сведения о последнем из найденных клиентов, со­храняется в глобальной переменной п.

■ search3 производит поиск должников по отрицательному балансу и вычисляет суммарный баланс bal в пределах списка.

■ array_new записывает сведения о новом клиенте в ближайший свобод­ный элемент массива с индексом К. Цикл while позволяет записать любое количество клиентов до полного заполнения массива.

■ array_old корректирует сведения о старом клиенте. Поиск клиента по выбору оператора может производиться по номеру или по имени. Ва­риант корректировки реализует переключатель. Для обновления све­дений обновляется вся запись о клиенте. Для исключения клиента ему присваивается нулевой номер и производится его обмен в массиве с клиентом под последним номером К—1. Далее контролируемое коли­чество заполненных элементов массива уменьшается на 1. Цикл while позволяет обработать данные о любом количестве клиентов.

Класс File (см. рис. 4.62 и 4.63) содержит функции для записи в файл и считывания из файла.

■ openf производит выбор файла для записи и считывания. При этом ис­пользуются функции класса Cntr с помощью объекта оЬС типа Cntr — элемента класса File.

■ readf открывает файл для считывания, считывает данные о клиентах и размещает их в массиве. После окончания считывания файл закры­вается.

■ writef после предъявления пароля открывает файл для записи, запи­сывает данные из массива и закрывает файл.

Данные и функции класса File с атрибутом static и функция sum будут рассмотрены далее в параграфе 4.7.

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

 

// Файл CLASSNbank.h

// Рис. 4.62. Объявление классов Client, Sort и File #ifndef BANK tdefine BANK

#include " c: \cpp\class\\cntr.h" //Рис.4.58

#define N 10//макс.количество клиентов в одном списке

#define passwf " passw.txt" //< baHn для размещения пароля

//структура client struct client{int number;

STRING name[11];

float balance; };

 

//класс Client class Client{ public:

int К; //текущее количество

//заполненных элементов массива m

float bal; //баланс в пределах списка

client m[N]; //массив объектов структурного типа

Client();

~Client(); }; //конец объявления класса Client //класс Sort

class Sortrpublic Client {

void swop(int, int); //обмен значениям

void search(); //поиск свободного номера в массиве

void searchl(); //поиск по номеру

void search2(); //поиск по имени

public:

Sort();

-Sort ();

void sort(int); //сортировка массива

void sortl(); //сортировка массива с ручным

//вводом индекса void screen (); //вывод массива на экран void search3(); //поиск по отрицат. балансу void array_new(); //запись в массив нового клиента void array_old(); //работа со старым клиентом }/ //конец объявления класса Sort

 

// класс File

class Filerpublic Sort {

static float sbal; //общий баланс, статический элемент public: File (); -File ();

static float getbal(); //возвращает общий

//баланс, статическая функция static int sK; //общее количество клиентов, статический элемент Cntr оЬС; //объект типа Cntr fstream ob; //объект-файл void openf(); //выбор файла-списка void readf(); //считывание из файла void writef(); //запись в файл

void sum(); //подсчет общего количества клиентов и общего баланса }; //конец объявления класса File

 

tinclude " с: \cpp\class\passw.срр" //предъявл. пароля, рис.4.65 #include " с: \cpp\class\\pgsl.срр" //ввод/вывод структурного

//объекта, рис.4.б4
♦ include " с: \cpp\class\bank.срр" //описание функций-элементов, рис. 4.63
#endif __________________________________________

Рис. 4.62. Объявление классов Client, Sort и File

 

//файл CLASSXbank.срр

//Рис. 4.63 Классы Client, Sort, File
//Описание функций-элементов
int File:: sK=0; //начальные значения

float File:: sbal=.ООО; //статич.элементов

 

Client:: Client() {К=0; } Client:: ~Client() { }

void Sort:: swop(int i, int j)

{client c=m[i]; m[i]=m[j]; m[j]=c; }//обмен значениям

 

Sort:: Sort(): Client () { } Sort:: -Sort(){ }

 

void Sort:: sort(int ind)

{ for(int i=0; i< K-l; i++){for(int j=i+l; j< K; j++) { switch (ind) { //выбор вида сортировки case 1:

if (m[i].number > m{j].number) swop(i, j); break; case 2:

if (strcmp(m[i].name, m[j1.name)> 0)swop(i, j); break; case 3:

if (m[i].balance > m[j].balance)swop(i, j); break; default: cout«" \пвведена ошибочная MeTKa" < < endl; goto mm; /*оператор перехода к метке mm*/}; }; }; тт: /*метка для goto*/; }

void Sort:: sortl() //сортировка с вводом и выводом на экран {for(int i=0; i< 10; i++){

сои^< " \пвыберите параметр сортировки: "

«" \nl-no номеру счета, 2-по имени, " «" 3-по балансу, 0-окончание"; int ind; cin»ind; cout«" \n выбран индекс "

«ind«endl; if (ind—0) break; sort(ind); screen(); }; }

 

void Sort:: screen (){clrscr ();

cout«" \n СОДЕРЖИМОЕ СПИСКА: ";

cout< < K«" клиентов";

for(int i=0; i< K; i++) {

if (m[i].number! =0) cout«m[i];

if(i> 0 & & i%5==0) pause(9); }; pause(9); }

 

void Sort:: search(){int j=l; do{num=j;

for(int i=0; i< K; i++){

if(m[i].number==j){/*номер j занят*/j++; break; }; };

if (num==j) {cout< < " \n номер " «num«" свободен *'; break; };

}while(j< =N);

if(j> N) {cout«" \n список заполнен "; num=N+l; }; pause(9); }

 

void Sort:: searchl(){int l, iN=N;

cout«" \n введите искомый номер от 1 до " «iN«' '; cin»l; int k=0; for(int i=0; i< K; i++)

{if (l==m[, i].number) {cout«m[i]; k++; n=i; }; }; if (k==0) cout«" \n номер свободен "; if (k> l) cout«" \n ошибка, повторите номер "; pause (9); }

 

void Sort:: search2 (){

cout< < " \пвведите искомую фамилию ";

STRING f[10]; cin»f;

int k=0; for(int i=0ri< K; i++){


if(strcmp(f, m[i].name)==0)

{cout«m[i]; k++; n=i; }; };

if(k==0)cout< < " клиент не найден ";

if (k> l) cout«" однофамильцы"; pause(9); }

 

void Sort:: search3(){int k=0; bal=.000; for(int i=0; i< K; i++){bal+=m[i].balance; if (m[i].balance< 0.) {cout«m[i]; k++; if(i> 0 & & i%5==0)pause(9); }; }; cout«" \n КОЛИЧЕСТВО ДОЛЖНИКОВ= " «k

«" \n баланс списка=" «Ьа1; pause (9); }

 

void Sort:: array_new(){int jj=l; while(jj! =0 & & K< N){ cout< < " \пввод данных клиента\п"; search (); cin»m [К]; cout«m [К]; K++; cout< < " \n окончание: введите ноль"

< < " \п продолжение: введите любое число "; cin»jj; }; if(K==N)cout< < " \n список заполнен"; pause(9); }

void Sort:: array_old(){ int jj=l; while(jj! =0){

cout< < " \n поиск клиента по номеру: введите 1 "

< < " \п поиска клиента по имени: введите 2 "; int 1; cin»l; if (1==1) searchl ();

if(1==2)search2(); //вызов функции поиска cout< < " \n отказ от корректировки: введите ноль "

< < " \п перезапись: введите 1 "

< < " \п удаление клиента: введите 2 ";

int kk; cin»kk; switch(kk) { case 0: break;

case 1: {cin> > m[n]; }; break;

case 2: {m[n].number=0; swop(n, K-l); K—; }; break; /* корректируются записи о последнем из найденных клиентов*/ default: cout«" \n введена непредусм. метка";

}//конец преключателя cout< < " \n окончание: введите ноль"

< < " \п продолжение: введите любое число "; cin»jj; }; pause (9); }

 

File:: File (): Sort () { } File:: -File(){ }

 

void File:: openf(){obC.init(); obC.report(); int i, j;

do{ cout«" \nBBeflMTe номер выбранного списка "; cin»i;

if (i< 0 I I i> 9)

{cout«" \n введен недопустимый номер, повторите "; pause(9); j=l; } else j=0; }while(j! =0); obC.box[3]=(char)(48+i); /*48-код ноля*/ }


void File:: readf(){

ob.open(obC.box, ios:: in I ios:: nocreate);

filetest(ob); /*файл не откроется,

если он ранее не существовал*/

К=0; while (! ob.eof()) {ob»m [К]; К+ +; }; К--;

cout«" \n считаны данные " < < К«" клиентов";

ob.close ();

cout«" СЧИТЫВАНИЕ ИЗ СПИСКА ОКОНЧЕНО"; pause (9); }

 

void File:: writef () { cout< < passw; //предъявление пароля

ob.open(obC.box, ios: rout | ios: rnocreate | ios:: trunc); filetest(ob);

/*при перезаписи прежнее содержимое файла удаляется, файл не откроется, если он ранее не существовал */ for (int i = 0; i< K; i++) ob«m[i]; ob.close();

cout«" \n ЗАПИСЬ В СПИСОК ОКОНЧЕНА"; pause (9); } float File:: getbal(){return sbal; } void File:: sum(){sK+=K; sbal+=bal; }

 

Рис. 4.63. Описание функций классов Client, Sort и File

 

Применительно к разрабатываемому программному обеспечению пере­гружены (рис. 4.64) операторы» и «непосредственно для структурного объекта типа client. Разделение вариантов для монитора и файла продикто­вано целевым форматированием и режимами открывания соответствующих файлов. Оператор-функции записаны в файл CLASS \pgsl.cpp. Использо­ван ранее разработанный манипулятор word (рис. 4.34).

 

//файл CLASS\pgsl.срр

//Рис. 4.64 Ввод/вывод структурного объекта //перегрузка > > и «для структурного объекта tinclude " c: \cpp\class\\word.cpp" //Рис.4.34

 

// < < для вывода (вставки в поток)

ostream & operator< < (ostream sstream, client obc)

{ stream«' \n ';

stream.width(4);

stream < < obc.number;

stream.width(14);

stream < < obc.name;

stream.setf(ios:: right I ios:: fixed); stream.width(12); stream.precision(2); stream < < obc.balance; if (obc.balance< 0) stream< < word; return stream; } //для монитора-вывод на экран

fstream & operator«(fstream sstream, client obc) {stream«1 \n';

stream < < obc.number;

streara«1 ';

stream «obc.name;

stream«' ';

stream < < obc.balance;
return stream; } //для файла-запись

 

//» для ввода (извлечения из потока)

istream & operator»(istream & stream, client & obc)

{сои^< " введите номер "; stream»obc.number;

cout< < " введите фамилию "; stream> > obc.name;

cout< < " BBeflHTe баланс "; stream»obc. balance; return stream; } //для монитора-ввод с клавиатуры

 

fstream & operator»(fstream sstream, client & obc) {stream»obc. number;

stream> > obc.name;

stream»obc. balance; return stream; } -//для файла -считывание

 

Рис. 4.64. Перегрузка операторов «и» для структурного объекта client

 

Показанная ранее программа проверки пароля (рис. 4.36) неудобна для практического использования. Преобразуем ее следующим образом:

■ будем хранить пароль в отдельном файле passw.txt,

■ функция passw_write для создания файла passw.txt, записи (переза­писи) пароля показана на рис. 4.65.

■ алгоритм passw для предъявления пароля в виде манипулятора для по­тока ostream (рис. 4.65) считывает пароль из файла и сравнивает со сло­вом, введенным оператором. Разрешены только две попытки. После двух ошибочных вводов производится принудительный выход в ОС.

Обе функции записаны в файл CLASS \passw.cpp.

 

// файл CLASSXpassw.срр //Рис. 4.65 Пароль

//Запись пароля в спец. файл " passw.txt" void passw_write (){

ofstream FILE(passwf, ios:: trunc); //открыт файл для записи
filetest (FILE); //пароля со стиранием предыдущего

 

сои^< " введите пароль в файл Vpassw.txt\" \n" < < " не более ЧЕТЫРЕХ символов" «" ХпПРЕДЫДУЩАЯ ЗАПИСЬ БУДЕТ СТЕРТА!! \п" «" ДЛЯ ОТМЕНЫ НАЖМИТЕ ESC, "

«" \пДЛЯ ПРОДОЛЖЕНИЯ-ЛЮБУЮ КЛАВИШУ\п"; pause{9); char password[5]; cin> > password; //ввод пароля FILE< < password; //запись пароля в файл FILE.close(); //файл закрыт } //Предъявление пароля (манипулятор программиста)

ostream & passw(ostream sstream)

{ char word[5], //для предъявления пароля

password[5]; //для заданного пароля ifstream FILE1(passwf); //открыт файл с паролем filetest (FILED;

FILEl»password; //считывание пароля из файла passw.txt FILE1.close(); //файл закрыт

 

сои^< " \пвведите пароль-не более ЧЕТЫРЕХ символов"

< < " \п разрешены всего две попытки!! \п"; int m=l;

while (m< 3) { cin> > word; //ввод пароля if(strcmp(word, password)==0)

{сог^«" \ппароль верен\ппродолжим работу\п"; break; }//пароль верен m++;

if (m==2) {cout«" \n повторите ввод\п"; }; }; //пароль неверен if (m==3) {cout< < " \nBbixofl в ОС, нажмите любую клавишу "; pause(9); exit(1); }; //принудительный выход в ОС return stream; }

 

Рис. 4.65. Запись пароля в файл. Предъявление пароля

 

Используя описанное программное обеспечение, можно реализовать раз­личные программы. Приведем два примера: программу для первичного за­полнения базы данных и программу для корректировки базы данных.

Первичное заполнение файла-списка реализует программа на рис. 4.66а. Результат исполнения этой программы показан на рис. 4.666 (4 кадра).

Кадр 1: запись пароля в файл.

Кадр 2: заполнение массива сведениями о двух клиентах, поиск долж­ников. Отрабатывают функции array_new и search3.

Кадр 3: выбор файла-списка (№ 4) для записи, предъявление пароля, за­пись в файл. Отрабатывают функции openf и writef. Окончание работы. Если бы пароль был дважды назван неверно, соответствующая запись в кад­ре выглядела бы, как показано на рис. 4.666, кадр 3').

Кадр 4: аналогично выполнена запись 10 клиентов в файл-список № 9 (на рисунке показан конец записи, клиент с номером 10). Ввод пароля и за­пись в файл не показаны.

Распечатки полученных текстовых файлов-списков показаны на рис. 4.67 и 4.68.

 

// Файл PART4\FILES\4_66.cpp

// Рис. 4.66а. Создание базы данных

// первичная запись

♦ include " c: \cpp\class\\bank.h" //Рис. 4.62 main (){

cout«" \n3AnMCb ПАРОЛЯ"; passw_write (); pause(0); cout«" \n ПРОГРАММА УПРАВЛЕНИЯ БАЗОЙ ДАННЫХ"; char с;


do{File ob;

ob.array_new(); //заполнение массива

ob.search3(); //поиск должников, подведение баланса
ob.openf(); //выбор файла-списка

ob.writef(); //запись

cout«" \n в файл записано " «ob.K«" клиентов end"; cout«" \n переход к следующему списку: введите у" «" \n окончание работы: введите n "; cin»c; }while(с==1 у1); pause (9); return 0; }

 

Рис. 4.66а. Первичное заполнение базы данных

(Inactive C: \CPP\PART4\FILES44_66.EXE) £ Щ Ш \


 
 

введите пароль в файл " pass.txt"

; не более ЧЕТЫРЕХ символов

ПРЕДЫДУЩАЯ ЗАПИСЬ БУДЕТ СТЕРТА •?

ДЛЯ ОТМЕНЫ НАЖМИТЕ ESC,

ДЛЯ ПР0Д0ЛЖЕНИЯ-ЛЮБ9Ю КЛАВИШУ

cat


Рис. 4.666 (кадр 1). Результат исполнения программы на рис. 4.66а

C: \CPP\PART4\FILES\4 66.ЕХЕ

ПРОГРАММА УПРАВЛЕНИЯ БАЗОЙ ДАННЫХ |ввод данных клиента

|

; номер 1 свободен введите номер 1 введите Фамилию кошкин введите баланс -44


.1 кошкин -44.00 ДОЛЖНИК

окончание: введите ноль \ продолжение: введите любое число 3


m


ввод данных клиента

номер 2 свободен введите номер 2 введите Фамилию мышкин (введите баланс 18

2 мышкин 18.00

| окончание: введите ноль | продолжение: введите любое число 0

1 кошкин -44.00 ДОЛЖНИК

КОЛИЧЕСТВО Д0ЛЖНИК0В=1 баланс списка=-26.00


Рис. 4.666 (кадр 2).

клиента в массив


Результат исполнения программы на рис. 4.66а. Ввод данных


C: \CPP\PART4\FILES\4 G6.EXE


ввод имени управл. Файла без расшир., не более ч символов ЬохО

зарегистрированные списки: 4 boxU.box 9 DOX9.DOX введите номер выбранного списка ч

введите лароль-не более ЧЕТЫРЕХ символов

разрешены всего две попытки ft cat

пароль верен " продолжим работу

ЗАПИСЬ В СПИСОК ОКОНЧЕНА в Файл записано 2 клиентов end переход к следующему списку: введите у окончание работы: введите п у_


 

 

Щ

 

Ям-

I


Рис. 4.666 (кадр 3). Результат исполнения программы на рис. 4.66а Пароль верен. Произведена запись в файл Ьох4.Ьох

В (Inactive C: \CPP\PART4\FILES\4_6G.EXE)


введите пароль-не более ЧЕТЫРЕХ символов разрешены всего две попытки?!

dog 5£ а

повторите ввод Frog

выход в ОС, нажмите любую клавишу_


Рис. 4.666 (кадр 3'). Результат исполнения программы на рис. 4.66а. Пароль неверен

CACPP\PART4\F1LES\4 66.ЕХЕ

ввод данных клиента

номер 10 свободен введите номер 10 введите Фамилию ананасов введите баланс 2

10 ананасов 2.00

окончание: введите ноль продолжение: введите любое число 0


список заполнен 2 индюков ч голубев б Лебедев 9 лимонов КОЛИЧЕСТВО должников=и баланс списка=83.80


-1.10 ДОЛЖНИК -8.00 ДОЛЖНИК

-U.00 должник -0.10 должник


Рис. 4.666 (кадр 4). Результат исполнения программы на рис. 4.66а. Ввод данных клиента в массив (показан ввод для последнего клиента номер 10)

1^2 Ьох4.Ьок - Блокнот  
Файл.. Правка * Поиск  
Справка «
|l кошкин -44  
2 мышкин 18 " Ш-
Ш f  

Рис. 4.67. Файл-список Ьох4.Ьох, созданный программой на рис. 4.66а

 

lij Ьох9.box - блокноте  
; $9йя: Цр«ка _ Подо? '" Справка
2 индюков -1.1  
3 воробьев 12  
4 голубев -8  
5 петухов 16  
6 Лебедев -4  
7 чижик 11  
|8 курочкин 34  
9 лимонов -0.1 -
10 ананасов 2  
   

Рис. 4.68. Файл-список ЬохЭ.Ьох, созданный программой на рис. 4.66а

 

Корректировку списков реализует программа на рис. 4.69а, результат исполнения показан на рис. 4.696 (10 кадров).

 

//файл PART4\FILES\4_69.cpp //Рис. 4.69а Корректировка базы данных //Управление банковской базой данных ♦ include " с: \cpp\class\\bank.h" //Рис. 4.62

 

main () {

cout«" \n КОРРЕКТИРОВКА БАЗЫ ДАННЫХ";

char с;

do{File ob;

ob.openf(); //выбор файла-списка

ob.readf(); pause(9); //считывание

ob.screen(); pause(9); //вывод на экран

ob.array_new(); pause(9); //новый клиент

ob.array_old(); pause(9); //старый клиент

ob.sortl (); pause(9); //сортировка списка

ob.search3(); pause(9); //поиск должников, подведение баланса ob.writer(); //запись

cout«" \nB файл записано " «ob.K«" клиентов, end"; cout< < " \n переход к следующему списку: введите у"

< < " \п окончание работы: введите n "; cin> > c; }while(с==1 у'); pause(9); return 0; }

Кадр 1: после обращения к управляющему файлу ЬохО.Ьох выбирается из имеющихся (№ 4 и № 9) список для корректировки (№ 9), содержимое ко­торого считывается в массив. Отрабатывают функции openf и readf.

 

\Ш C: \CPP\PART4\FILES\4_69.EXE    
КОРРЕКТИРОВКИ БАЗЫ ДАННЫХ. ввод имени управл. файла без расшир., не более ч символов ЬохО    
зарегистрированные списки: ; Ч d0x4.D0X 9 Ьох9.Ьох введите номер выбранного списка 9    
' считаны данные 10 клиентов СЧИТЫВАНИЕ ИЗ СПИСКА ОКОНЧЕНО.  
    -2Ы

Рис. 4.696 (кадр 1). Результат исполнения программы на рис. 4.69а

C: \CPP\PART4\FILES44 69.ЕХЕ


1 2 3 4 5 6 7 8 9 10

СОДЕРЖИМОЕ СПИСКА: 10

гусев индюков

воробьев голубев петухов Лебедев чижик

курочкин лимонов

ананасов

клиентов 22.00

-1.10 ДОЛЖНИК 12.00

-8.00 ДОЛЖНИК 16.00

-4.00 ДОЛЖНИК

11.00

34.00

-0.10 ДОЛЖНИК 2.00


список заполнен.

1^

 

Рис. 4.696 (кадр 2). Результат исполнения программы на рис. 4.69а


В CACPP4PART4\FILES\4_69.EXE


■ ШИШ


 
 

поиск клиента по номеру: введите 1 поиска клиента по имени: введите 2 1

введите искомый номер от 1 до 10 6

6 Лебедев -4.00 ДОЛЖНИК

отказ от корректировки: введите ноль перезапись: введите 1 удаление клиента: введите 2 2

окончание: введите ноль продолжение: введите любое число 5


Кадр 2: на экран выводится содержимое выбранного списка № 9. Ра






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.