Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

алгоритмизация и программирование 16 глава




{

string s;

getline(cin,buff); // очистка буфера

cout<<" Введите искомое название планеты:";

getline(cin,s);;

system("CLS");

bool f=true;

cout<<endl<<endl<<endl;

for (int i=1; i<=n; i++)

if (mas[i].planeta==s)

{

cout<<" Название планеты: "<<mas[i].planeta<<endl;

cout<<" Расстаяние то Солнца: "<<mas[i].rasst<<endl;

cout<<" Период обращения: "<<mas[i].period<<endl;

cout<<" Наличие спутника: "<<mas[i].sputnik<<endl;

cout<<" Основной состав атмосферы: "<<mas[i].sostav<<endl;

f=false;

}

if (f) cout<<" Такой планеты нет!"<<endl;

system("pause");

}

 

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

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


15. Файлы

Файлом называют способ хранения информации на физическом устройстве. Файл – это понятие, которое применимо ко всему – от файла на диске до терминала.

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

В отличие от Си, в С++ файловые потоки обслуживаются с использованием потоковых классов на основе библиотек <ifsream> и <ofstream>. Рассмотрим каждый из этих способов подробнее.

15.1. Подход с использованием возможностей языка Си

В Си существует два типа потоков: текстовые (text) и двоичные (binary).

Текстовый поток – это последовательность символов. При передаче символов из потока на экран, часть из них не выводится (например, символ возврата каретки, перевода строки).

Двоичный поток –это последовательность байтов, которые однозначно соответствуют тому, что находится на внешнем устройстве.

Прежде чем читать или записывать информацию в файл, он должен быть открыт и тем самым связан с потоком. Это можно сделать с помощью библиотечной функции fopen(). Она берет внешнее представление файла (например, c:\my_prog.txt) и связывает его с внутренним логические именем, которое используется далее в программе. Логическое имя – это указатель на требуемый файл. Его необходимо определить; делается это, например, так:

FILE *fp;

Здесь FILE – имя типа, описанное в стандартном заголовочном файле stdio.h, fp – указатель на файл. Обращение к функции fopen() в программе осуществляется выражением:

fp = fopen("спецификация_файла",

"способ_использования_файла");

Спецификация файла (т.е. физическое имя файла и путь к нему) может, например, иметь вид: "c:\\my_prog.txt" – для файла my_prog.txt на диске с:.

Способ использования файла задается следующими символами:

• r – (от read) открыть существующий файл для чтения;

• w – (от write) создать новый файл для записи (если файл с указанным именем существует, то он будет переписан);

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

Тип файлового потока задается ключом t (текстовый) или b (бинарный). Если режим t или b не задан (например, r, w или а), то он определяется значением глобальной переменной _fmode. Если fmode=0_BINARY, то файлы открываются в двоичном режиме, а если _fmode=0_TEXT – в текстовом режиме. Константы 0_BINARY и 0_ТЕXТ определены в файле fcntl.h.

Если в результате обращения к функции fopen() возникает ошибка, то она возвращает указатель на константу NULL.

Рекомендуется использовать следующий способ открытия файла:

if ((fp = fopen("c:\\my_prog.txt", "rt")) == NULL)

{

puts("Открыть файл не удалось\n")

return 0;

}

После окончания работы с файлом он должен быть закрыт. Это делается с помощью библиотечной функции fclose(). Она имеет следующий прототип:

int fclose(FILE *fp);

При успешном завершении операции функция fclose() возвращает значение нуль. Любое другое значение говорит об ошибке.

Рассмотрим стандартные функции для работы с файлами последовательного доступа:

1. Функция putc() записывает символ в файл и имеет следующий прототип:

int putc(int с, FILE *fp);

Здесь fp – указатель на файл, возвращенный функцией fopen(), с - символ для записи (переменная с имеет тип int, но используется только младший байт). При успешном завершении putc() возвращает записанный символ, в противном случае возвращается константа EOF. Она определена в файле stdio.h и имеет значение (-1).

2. Функция getc() читает символ из файла и имеет следующий прототип:

int getc(FILE *fp);

Здесь fp – указатель на файл, возвращенный функцией fopen(). Эта функция возвращает прочитанный символ. Соответствующее значение имеет тип int, но старший байт равен нулю. Если достигнут конец файла, то getc возвращает значение ЕОF.

3. Функция feof() определяет конец файла при чтении двоичных данных и имеет следующий прототип:

int feof(FILE *fp);

Здесь fp – указатель на файл, возвращенный функцией fopen(). При достижении конца файла возвращается ненулевое значение, в противном случае возвращается 0.

4. Функция fputs() записывает строку символов в файл. Она отличается от функции puts() только тем, что в качестве второго параметра должен быть записан указатель на переменную файлового типа.

Например:

fputs("Ехаmple", fp);

При возникновении ошибки возвращается значение EOF.

5. Функция fgets() читает строку символов из файла. Она отличается от функции gets() тем, что в качестве второго параметра должно быть записано максимальное число вводимых символов плюс единица, а в качестве третьего – указатель на переменную файлового типа. Строка считывается целиком, если ее длина не превышает указанного числа символов, в противном случае функция возвращает только заданное число символов. Рассмотрим пример:

fgets(string, n, fp);

Функция возвращает указатель на строку string при успешном завершении и константу NULL в случае ошибки либо достижения конца файла.

Рассмотрим другие библиотечные функции, используемые для работы с файлами прямого доступа (все они описаны в файле stdio.h):

1. Функция fseek() позволяет выполнять чтение и запись с произвольным доступом и имеет следующий прототип:

int fseek(FILE *fp, long count, int access);

Здесь fp – указатель на файл, возвращенный функцией fopen(), count – номер байта относительно заданной начальной позиции, начиная с которого будет выполняться операция, access – способ задания начальной позиции.

Переменная accessможет принимать следующие значения:

0 – начальная позиция задана в начале файла;
1 – начальная позиция считается текущей;
2 – начальная позиция задана в конце файла.

При успешном завершении возвращается нуль, при ошибке – ненулевое значение.

2. Функция ferror() позволяет проверить правильность выполнения последней операции при работе с файлами. Имеет следующий прототип:

int ferror(FILE *fp);

В случае ошибки возвращается ненулевое значение, в противном случае возвращается нуль.

3. Функция remove() удаляет файл и имеет следующий прототип:

int remove(char *file_name);

Здесь file_name – указатель на строку со спецификацией файла. При успешном завершении возвращается нуль, в противном случае возвращается ненулевое значение.

4. Функция rewind() устанавливает указатель текущей позиции в начало файла и имеет следующий прототип:

void rewind(FILE *fp);

5. Функция fread() предназначена для чтения блоков данных из потока. Имеет прототип:

unsigned fread(void *ptr, unsigned size,

unsigned n, FILE *fp);

Она читает n элементов данных, длиной size байт каждый, из заданного входного потока fp в блок, на который указывает указатель ptr. Общее число прочитанных байтов равно произведению n*size. При успешном завершении функция fread() возвращает число прочитанных элементов данных, при ошибке – 0.

6. Функция fwrite() предназначена для записи в файл блоков данных. Имеет прототип:

unsigned fwrite(void *ptr, unsigned size,

unsigned n, FILE *fp);

Она добавляет n элементов данных, длиной size байт каждый, в заданный выходной файл fp. Данные записываются с позиции, на которую указывает указатель ptr. При успешном завершении операции функция fwrite() возвращает число записанных элементов данных, при ошибке – неверное число элементов данных.

15.2. Подход с использованием возможностей языка С++

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

Файловый поток для чтения открывается следующим образом:

ifstream идентификатор_потока(имя_файла,ключи_потока);

Например:

ifstream input("input.txt", ios::in);

Здесь открывается файловый поток с идентификатором input для чтения из файла. Такой файловый поток должен быть по аналогии с Си обязательно закрыт: input.close();

Файловый поток для записи открывается так:

ofstream идентификатор_потока(имя_файла,ключи_потока);

Например:

ofstream output("output.txt", ios::out);

Этот поток также должен быть закрыт:

output.close();

Как же работать с такими потоками? Очень просто:

int main()

{

int n,k;

float f;

char str[100];

ifstream input("input.txt", ios::in);

ofstream output("output.txt", ios::out);

input>>n;

input>>k;

n=n+k;

output<<n<<endl;

input>>f;

f=f+2;

output<<f<<endl;

input>>str; output<<str<<”, “;

input>>str; output<<str<<”!!”;

input.close();

output.close();

return 0;

}

Если исходным содержимым файла input.txt было следующее:

-5.56783345

Hello world!

то в файл output.txt запишется следующее:

-3.56783

Hello, world!!!


Лабораторная работа № 15
Исследование методов доступа к файлам данных

ЦЕЛЬ РАБОТЫ: совершенствование навыков в программировании с использованием указателей, исследование функций последовательного и прямого доступа к файлам.

Выполнение работы: в соответствии с вариантом составить и реализовать программы.

Задание I

1. Работа с неструктурированными данными

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

1. Создать в Блокноте следующий текстовый файл:

У меня спросили: сколько будет x Опер y?

А я не знаю! А n Опер k? Тоже!

Помогите!

Например:

У меня спросили: сколько будет 7 * 2?

А я не знаю! А 9 / 4? Тоже!

Помогите!

2. Вам известна структура файла. Вывести содержимое файла на экран, а в выходной файл записать результаты:

x Опер y = Рез1

n Опер k = Рез2

Например:

7 * 2 = 14

9 / 4 = 2.25

3. Исходные данные берутся из таблицы согласно варианта:

Вар. x Опер y n Опер k Вар. x Опер y n Опер k
    +     *       +     *  
    -     /       -     /  
    *     -       *     -  
    /     +       /     +  
    +     /       +     /  
    -     *       -     *  
    *     +       *     +  
    /     -       /     -  

 

4. Исследовать возможность решения этой задачи с использованием трех способов:

• функциями последовательного доступа к файлам;

• функциями прямого доступа к файлам;

• файловыми потоками С++.

5. Сделать выводы о целесообразности использования того или иного метода считывания или записи данных в файл.

2. Работа со структурированными данными

1) Используя полученную при выполнении лабораторной работы 14 программу, реализовать возможность сохранения данных в файл с последующим чтением из файла введенных данных.

2) Исследовать возможность решения этой задачи с использованием трех способов:

• функциями последовательного доступа к файлам;

• функциями прямого доступа к файлам;

• файловыми потоками С++.

3) Сделать выводы о целесообразности использования того или иного метода считывания или записи структурированных данных в файл.

Задание II

В соответствии с вариантом написать и отладить программу:

1. Дана информация о четырех студентах. Структура имеет вид: фамилия, год рождения, место рождения, факультет. Вывести данные о самом старшем по возрасту студенте.

2. Дана информация о шести вкладчиках сберкассы. Структура имеет вид: фамилия, район, соц. положение и величина вклада. Вывести данные о фермерах. Подсчитать их количество.

3. Дана информация о пяти школах. Структура имеет вид: номер школы, год, количество выпускников, число поступивших в вузы. Вывести данные о школе с самым большим отношением числа поступивших к числу выпускников.

4. Дана информация о пяти студентах. Структура имеет вид: фамилия, имя, отчество и 4 оценки за экзамены. Вывести данные о студентах, сдавших сессию на отлично.

5. Дана информация о пяти рабочих цеха. Структура имеет вид: фамилия, пол, размер зарплаты, стаж работы. Вывести данные о рабочем с наибольшей зарплатой.

6. Дана информация о четырех вузах. Структура имеет вид: название вуза, число студентов, количество факультетов, количество кафедр. Вывести данные об общем числе студентов.

7. Дана информация о пяти студентах. Структура имеет вид: фамилия, имя, отчество и 4 оценки за экзамены. Вывести данные о студентах, сдавших сессию без троек.

8. Дана информация о шести вкладчиках сбербанка. Структура имеет вид: фамилия, район, соц. положение и величина вклада. Вывести данные о том, сколько среди вкладчиков служащих. Вычислить их суммарный вклад.

9. Дана информация о пяти больных. Структура имеет вид: фамилия, возраст, пол, давление. Вывести данные о больных с повышенным давлением (более 140) и подсчитать их количество.

10. Дана информация о пяти квартирах. Структура имеет вид: фамилия владельца, площадь, число комнат, этаж. Вывести данные о квартирах с площадью меньше 30 кв.м и подсчитать их количество.

11. Дана информация о шести студентах. Структура имеет вид: фамилия, год рождения, факультет и курс. Вывести данные о студентах в возрасте от 17 до 19 лет и их количестве.

12. Дана информация о шести вкладчиках банка. Структура имеет вид: фамилия, район, соц. положение и величина вклада. Вывести данные о вкладчиках района введенного с клавиатуры.

13. Дана информация о шести студентах. Структура имеет вид: фамилия, рост, вес, год рождения. Вывести данные о студентах с наименьшим ростом и весом от 65 до 75 кг.

14. Дана информация о пяти комнатах в общежитии. Структура имеет вид: факультет, номер комнаты и ее площадь, количество проживающих в ней студентов. Вывести данные о комнате, в которой наименьшая площадь на одного студента.

15. Дана информация о шести вкладчиках сберкассы. Структура имеет вид: фамилия, район, соц. положение и величина вклада. Вывести данные о вкладчике с самой большой величиной вклада.

16. Дана информация о пяти рабочих цеха. Структура имеет вид: фамилия, пол, размер зарплаты, стаж работы. Вывести данные о рабочем с максимальным стажем работы.

17. Дана информация о пяти спортсменах. Структура имеет вид: фамилия, пол, год рождения и рост. Вывести данные о самом высоком спортсмене старше 20 лет.

18. Дана информация о пяти изданиях. Структура имеет вид: название издания, газеты или журнала, стоимость одного экземпляра, количество экземпляров в год. Вывести на печать информацию о самом дешевом издании.

19. Дана информация о шести инвесторах банка. Структура имеет вид: фамилия, район, соц. положение и величина вклада. Вывести данные о том, каков суммарный вклад инвесторов определенного района.

20. Дана информация о шести студентах. Структура имеет вид: фамилия, рост, вес, цвет волос. Вывести данные о блондинах с максимальным ростом.

21. Дана информация о четырех вузах. Структура имеет вид: название вуза, число студентов, количество факультетов, количество кафедр. Вывести данные о вузе с максимальным числом студентов.

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

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

24. Дана информация о пяти рабочих цеха. Структура имеет вид: фамилия, пол, размер зарплаты, стаж работы. Вывести данные о мужчине с максимальной зарплатой.

25. Дана информация о пяти книгах. Структура имеет вид: название книги, автор, стоимость, количество листов. Вывести данные о заданной книге (по названию и автору) с минимальной стоимостью.

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

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

Контрольные вопросы

1. Понятие файла в C/C++.

2. Классификация файлов.

3. Какого типа могут быть компоненты файла?

4. Нужно ли при определении файла заранее указывать его длину?

5. Чем отличается файл от массива?

6. Понятие о логическом и физическом имени файла.

7. Что понимается под чтением из файла и что под записью в файл?

8. Типы доступа к файлам.

9. Что такое последовательный файл?


 

Лабораторная работа № 16
Исследование связанных списков данных

Цель занятия:

· Совершенствование навыков разработки программ в среде программирования MS Visual C++

· Совершенствование навыков в программировании с использованием указателей

· Исследование процесса формирования элементов связанного списка

· Исследование операций с элементами связанных списков

Время на выполнение работы: 4 часа

 

Программа исследований:

1. Исследование процесса формирования элементов связанного списка

2. Исследование операций с элементами связанных списков

Подготовка к выполнению работы:

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

2. Практически освоить порядок работы на ПЭВМ в среде программирования MS Visual C++.

Материалы для подготовки к занятию:

1. Конспект лекций

2. [1] стр. 114-119

Содержание отчета:

1. Цели исследования.

2. Программу работы.

3. Диаграммы работы операций с элементами связанного списка

4. Листинг программы

5. Результаты исследований

6. Выводы по каждому пункту и общий вывод.

 


МЕТОДИЧЕСКИЕ РЕКОМЕНДАЦИИ

1. Исследование формирования элементов связанного списка

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

 
*next
 
*next  
 
*next  
 
*next  

Рисунок 15.1 - Однонаправленный список

// описание структуры, позволяющей создать линейный список

Struct List

{ // -- поля данных --

char name[20]; // имя

Int age; // возраст

// -- поля связи ---

List *next; // указатель на следующий

}; // элемент списка

List *start; // start - специальный глобальный

// указатель для входа в список

// для пустого списка должен

// быть равен нулю

Для этого списка определены три операции:

- добавление нового элемента списка Add();

- удаление элемента из списка Del();

- переход к следующему элементу списка Next().

Рассмотрим их.

2. Исследование операций с элементами связанных списков

1. Добавление нового элемента списка Add().

// функция добавления элементов в список

List* Add(List *cur) // cur - текущий эл-т

{

// выделение памяти для нового элемента списка

List *p=(List*)malloc(sizeof(List)); // p - новый эл-т if(!p) // если выделить память не удалось

{

cout<<" Error!";

return 0;

}

if(!start) // если список пуст

{

start=p; // то новый элемент будет первым

p->next=NULL; // и последним в списке

return p;

}

// если список не пустой, то добавляем элемент

// после текущего и связываем новый элемент с

// последующим

p->next=cur->next;

cur->next=p; // связываем текущий элемент с новым

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...