Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ПрЭВМ ЛР №4 Строки и структуры

.pdf
Скачиваний:
19
Добавлен:
13.02.2015
Размер:
311.4 Кб
Скачать

ПрЭВМ, 1 семестр, направление «Прикладная математика и информатика»

1

Лабораторная работа №4.

Работа со строками и файлами. Структуры и массивы структур

Особенности работы со строками

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

ВС++ есть два вида строк:

С-строки (их еще называют строки старого стиля).

Класс стандартной библиотеки С++ string (строки нового стиля, будут рассмотрены в следующих лабораторных работах).

Для нединамических строк удобно задавать ее длину с помощью именованной константы. Однако нужно учитывать, что один символ на конце строки всегда занимает символ ее конца (нуль-символ). Поэтому, если необходимо задать строку длиной в n символов, то ее длина должна быть равна n + 1. Выход за границы строки и отсутствие нуль-символа являются распространенными причинами ошибок в программах.

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

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

Кроме привычных функций копирования и нахождения длины строки, библиотека string предоставляет также различные функции для сравнения строк и подстрок, объединения строк, поиска в строке символа и подстроки и выделения из строки лексем. В библиотеке определен целый ряд функций, проверяющих принадлежность символа какому-либо множеству, например, множеству букв, разделителей, знаков пунктуации, цифр и т.д. Эти функции можно узнать, обратившись к справочной литературе (например, Приложение 6 учебника, описание заголовочного файла <string.h> стр. 414-415, алфавитный перечень стр. 416-446).

Для консольного ввода-вывода строк используются либо объекты cin и cout, либо функции библиотеки gets, scanf и puts, printf. Ввод строки с помощью операции >> выполняется до первого пробельного символа. Для ввода строки, содержащей пробелы, можно использовать либо методы getline или get класса istream, либо функции библиотеки gets и scanf. Функциями семейства printf удобнее пользоваться в том случае, если в одном операторе требуется ввести или вывести данные различных типов. Если же работа выполняется только со строками, проще применять специальные функции для ввода-вывода строк gets и puts.

Особенности работы со структурами в C++

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

Элементы структуры называются полями. Поля могут быть любого основного типа, массивом, указателем, объединением или структурой. После описания структурного типа обязательно ставится точка с запятой. Для обращения к полю используется операция выбора: «точка» при обращении через имя структуры и «->» при обращении через указатель.

Подготовлено Латухиной Е.А., старшим преподавателем кафедры ПиВВ ИМИКТ САФУ

ПрЭВМ, 1 семестр, направление «Прикладная математика и информатика»

2

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

Мы будем использовать структуры в основном для работы с простейшими базами данных. Поэтому все рекомендации будут даваться в данном контексте.

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

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

Организация меню

Когда задания связаны друг с другом, например, разные алгоритмы для работы с одним массивом структур, удобно использовать меню пользователя. Реализуется оно, например, так:

int num=1; while (num){

cout<<"Enter 0 for exit"<<endl;

cout<<"Enter 1 for reading data from file"<<endl; cout<<"Enter 2 for printing data"<<endl; cin>>num;

switch (num){ case 0:break;

case 1:{//чтение данных из файла (задание №8) break;

}

case 2:{//вывод на экран (задание №9) break;

}

default:cout<<"Error!"<<endl;

}

}

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

Особенности работы с файлами

В качестве файлов рекомендуется брать тексты на русском или английском языке, сохраненные в формате текстового документа (*.txt). Предварительно файл необходимо подготовить. Во-первых, нужно найти (в Интернете, электронной книге, файлах справки, где-то еще) текст подходящего размера. Обычно хватает текста из нескольких тысяч символов, но для отладки можно использовать небольшие файлы. Во-вторых, необходимо отформатировать строки так, чтобы в одной было не больше 80 символов (это число является неофициальным стандартом размера строки текстового файла).

Ввод-вывод из файла может выполняться с помощью либо объектов классов ifstream и ofstream (ввод/вывод в стиле С++, теоретический материал в Учебнике, Глава 10), либо функций

Подготовлено Латухиной Е.А., старшим преподавателем кафедры ПиВВ ИМИКТ САФУ

ПрЭВМ, 1 семестр, направление «Прикладная математика и информатика»

3

ввода/вывода в стиле С (заголовочный файл <stdio.h>, алфавитный перечень функций в Учебнике на стр. 411-413, подробное описание стр. 416-446). Примеры работы с файлами см. в Практикуме, семинары 5 и 6.

Помните, что посимвольное чтение из файла неэффективно.

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

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

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

Особенности работы с русским языком

Существует некоторая проблема с использованием русского языка в консольных приложениях. Причины этого объясняются в Практикуме на стр. 17. Для того, чтобы символы кириллицы отображались корректно, нужно использовать один из следующих трех способов:

1. Использование специализированных функций.

Наиболее универсальный способ, работает всегда и не требует дополнительных настроек среды. Необходимо добавить в текст программы следующий код:

char bufRus[256];

char* Rus(const char* text) { CharToOemА(text, bufRus); return bufRus;

}

Для того, чтобы можно было использовать функцию CharToOemА(), подключите заго-

ловочный файл: #include<windows.h>

Функция Rus() получает в качестве аргумента строку, в качестве результата получается строка в другой кодировке, которая корректно отображается на экране.

Если необходимо считывать с клавиатуры строку на русском, то следует использовать функцию OemToCharA(). Она работает аналогичным образом и должна получать два аргумента, поэтому для удобства можно самостоятельно сделать функцию, аналогичную Rus().

2. Локализация.

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

setlocale( LC_CTYPE,""); //корректный вывод setlocale(LC_ALL, "C"); //корректное чтение с клавиатуры

Не забудьте подключить заголовочный файл #include <clocale>

Подготовлено Латухиной Е.А., старшим преподавателем кафедры ПиВВ ИМИКТ САФУ

ПрЭВМ, 1 семестр, направление «Прикладная математика и информатика»

4

Проблема локализации состоит в следующем. Для того чтобы ввод/вывод работал корректно, необходимо писать соответствующие строки каждый раз перед командами ввода или вывода. Если этого не делать, в некоторых случаях локализация отключается.

3. Настройка среды программирования.

Подключите заголовочный файл #include<windows.h>, в начало функции main() добавьте следующие строчки:

SetConsoleCP(1251);

SetConsoleOutputCP(1251);

После этого необходимо запустить программу и в свойствах появившегося окна выбрать шрифт Lucida Console. Теперь при вводе/выводе символов кириллицы не будет проблем.

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

Задания для всех

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

За каждую задачу из этого раздела, если не сказано иначе, можно получить не более 1 балла.

Строки С и файлы:

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

2.Для того, чтобы в программе можно было осуществлять различные действия вне зависимости от регистра, используются специальные функции tolower(c) и toupper(c), переводящие переданный им символ с в нижний и верхний регистр соответственно. Однако эти функции работают лишь для букв латинского алфавита. Напишите аналогичные функции, работающие с кириллицей.

3.Написать программу, которая проверяет, является ли введенная строка палиндромом (читается одинаково как слева направо, так и справа налево). Пробелы и другие символы, не являющиеся буквами, при проверке не учитываются (строка «А роза упала на лапу Азора» является палиндромом).

4.Имеется текстовый файл, содержащий некоторое количество строк длиной до 80 символов. Выяснить, содержится ли в файле заданная последовательность символов.

5.Имеется текстовый файл, содержащий некоторое количество строк длиной до 80 символов. Выяснить, сколько раз в тексте встречается введенное с клавиатуры слово.

6.Имеется текстовый файл, содержащий некоторое количество строк длиной до 80 символов. Найти и вывести на экран все восклицательные предложения.

7.(2 балла) Имеется текстовый файл, содержащий некоторое количество строк длиной до 80 символов. Составить словарь из слов, содержащихся в этом файле. Если слово входит в текст несколько раз, в словаре оно должно быть записано только однажды. Все слова должны быть в нижнем регистре. Словарь должен быть отсортирован в алфавитном порядке и сохранен в новом текстовом файле. Если словарь построен, но не отсортирован, дубли не удалены, за задание можно получить

не более одного балла. Структуры:

Подготовлено Латухиной Е.А., старшим преподавателем кафедры ПиВВ ИМИКТ САФУ

ПрЭВМ, 1 семестр, направление «Прикладная математика и информатика»

5

Все оставшиеся общие задачи необходимо выполнять в одной программе. Перед выполнением заданий необходимо подготовить текстовый файл, содержащий не менее 10 записей.

В текстовом файле хранится база небольшой библиотеки (не более 100 записей). Каждая строка файла содержит запись об одной выдаче книги. Формат записи: номер записи (число), фамилия и инициалы абонента (30 позиций, начинается с фамилии), дата выдачи (формат ДД/ММ/ГГГГ), количество дней (целое число), автор (20 позиций), название (20 позиций), год издания, цена.

Используя подготовленный файл, решите следующие задачи:

8.Написать функцию, которая читает данные из файла и заносит их в массив структурного типа.

9.Написать функцию, которая выводит данные из массива структур в виде таблицы.

10.Организовать пользовательское меню. Как это сделать, см. выше.

11.Написать функцию, осуществляющую поиск всех просроченных книг (поиск всех книг, которые на введенную с клавиатуры дату должны быть сданы).

12.Написать функцию, которая считывает базу из текстового файла и записывает ее в бинарный файл.

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

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

15.Вывести на экран содержимое бинарного файла, упорядочив список по фамилиям абонентов.

Индивидуальные задания

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

1.(1 балл) Решить следующую задачу:

Вариант 1. Даны целые положительные числа N1 и N2 и строки S1 и S2. Получить из этих строк новую строку, содержащую первые N1 символов строки S1 и последние N2 символов строки S2 (в указанном порядке).

Вариант 2. Дан символ C и строка S. Удвоить каждое вхождение символа C в строку S. Вариант 3. Дана строка, содержащая по крайней мере один символ пробела. Вывести подстроку, расположенную между первым и вторым пробелом исходной строки. Если строка содержит только один пробел, то вывести пустую строку.

Вариант 4. Дано целое число N (1 ≤ N ≤ 26). Вывести N первых прописных (то есть заглавных) букв латинского алфавита.

Вариант 5. Дана строка, содержащая по крайней мере один символ пробела. Вывести подстроку, расположенную между первым и последним пробелом исходной строки. Если строка содержит только один пробел, то вывести пустую строку.

Вариант 6. Дана строка, содержащая полное имя файла. Выделить из этой строки название последнего каталога (без символов «\»). Если файл содержится в корневом каталоге, то вывести символ «\».

Вариант 7. Дана строка-предложение на русском языке. Преобразовать строку так, чтобы каждое слово начиналось с заглавной буквы. Словом считать набор символов, не содержащий пробелов и ограниченный пробелами или началом/концом строки.

Вариант 8. Дано целое положительное число. Вывести символы, изображающие цифры этого числа (в порядке справа налево).

Подготовлено Латухиной Е.А., старшим преподавателем кафедры ПиВВ ИМИКТ САФУ

ПрЭВМ, 1 семестр, направление «Прикладная математика и информатика»

6

Вариант 9. Дан символ C и строки S, S0. Перед каждым вхождением символа C в строку S вставить строку S0.

Вариант 10. Дана строка, содержащая полное имя файла. Выделить из этой строки название первого каталога (без символов «\»). Если файл содержится в корневом каталоге, то вывести символ «\».

Вариант 11. Дано целое число N (> 0) и строка S. Преобразовать строку S в строку длины N следующим образом: если длина строки S больше N, то отбросить первые символы, если длина строки S меньше N, то в ее начало добавить символы «.» (точка).

Вариант 12. Дана строка. Подсчитать количество содержащихся в ней цифр.

Вариант 13. Дано целое число N (1 ≤ N ≤ 26). Вывести N последних строчных (то есть маленьких) букв латинского алфавита в обратном порядке (начиная с буквы «z»). Вариант 14. Дана строка, состоящая из русских слов, разделенных пробелами (одним или несколькими). Вывести строку, содержащую эти же слова, разделенные одним символом «.» (точка). В конце строки точку не ставить.

Вариант 15. Дана строка. Если она представляет собой запись целого числа, то вывести 1, если вещественного (с дробной частью) — вывести 2; если строку нельзя преобразовать в число, то вывести 0. Считать, что дробная часть вещественного числа отделяется от его целой части десятичной точкой «.».

Вариант 16. Дано целое положительное число. Вывести символы, изображающие цифры этого числа (в порядке слева направо).

Вариант 17. Дан символ C и строки S, S0. После каждого вхождения символа C в строку S вставить строку S0.

Вариант 18. Дана строка, содержащая полное имя файла, то есть имя диска, список каталогов (путь), собственно имя и расширение. Выделить из этой строки имя файла (без расширения).

Вариант 19. Дан символ C, изображающий цифру или букву (латинскую или русскую). Если C изображает цифру, то вывести строку «digit», если латинскую букву — вывести строку «lat», если русскую — вывести строку «rus».

Вариант 20. Дана строка. Подсчитать количество содержащихся в ней прописных латинских букв.

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

Вариант 22. Дана строка. Подсчитать общее количество содержащихся в ней строчных латинских и русских букв.

Вариант 23. Дана строка, изображающая арифметическое выражение вида «<цифра>±<цифра>±…±<цифра>», где на месте знака операции «±» находится символ «+» или «–» (например, «4+7–2–8»). Вывести значение данного выражения.

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

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

Вариант 26. Дана строка-предложение с избыточными пробелами между словами. Преобразовать ее так, чтобы между словами был ровно один пробел.

Вариант 27. Дана строка, состоящая из русских слов, разделенных пробелами (одним или несколькими). Вывести строку, содержащую эти же слова, разделенные одним пробелом и расположенные в алфавитном порядке.

2.(2 балла) Имеется текстовый файл «test.txt», содержащий некоторое количество строк длиной до 80 символов.

Подготовлено Латухиной Е.А., старшим преподавателем кафедры ПиВВ ИМИКТ САФУ

ПрЭВМ, 1 семестр, направление «Прикладная математика и информатика»

7

Замечание: если задача будет решена только для одной строки, за задание можно получить не больше одного балла. Готовое задание предоставлять преподавателю вместе с примером файла, которые содержит все возможные варианты исходных данных. В любом случае в файле должно быть не менее 10 строк связного текста (из них не менее одной строки, содержащей ровно 80 символов).

Найти и вывести на экран:

Вариант 1: все строки в обратном порядке. Вариант 2: строки, содержащие числа.

Вариант 3: все слова, начинающиеся с гласных.

Вариант 4: цитаты, т.е. слова и фразы, заключенные в кавычки. Вариант 5: весь текст в обратном порядке.

Вариант 6: количество слов в каждой строке. Вариант 7: самое длинное слово.

Вариант 8: сначала все вопросительные, потом все восклицательные предложения. Вариант 9: количество слов, которые содержат хотя бы одну букву «а».

Вариант 10: все слова, начинающиеся и заканчивающиеся на гласные.

Вариант 11: количество слов, которые содержат ровно три буквы «а» (не обязательно подряд!).

Вариант 12: весь текст, меняя местами каждые два соседних слова. Вариант 13: количество однобуквенных слов.

Вариант 14: самое короткое слово каждой строки. Вариант 15: самое длинное слово каждой строки.

Вариант 16: все слова длиной меньше чем n (n вводится с клавиатуры). Вариант 17: все слова, которые начинаются с заглавных букв.

Вариант 18: все слова длиной больше чем n (n вводится с клавиатуры). Вариант 19. количество гласных букв в каждой строке.

Вариант 20: предложения, не содержащие чисел.

Вариант 21: предложения, начинающиеся с однобуквенных слов. Вариант 22: предложения, не содержащие запятых.

Вариант 23: все слова, которые начинаются и оканчиваются одной и той же буквой. Вариант 24: предложения, не содержащие знаков препинания кроме знака конца предложения.

Вариант 25: все слова длины n (n вводится с клавиатуры).

Вариант 26: предложения, содержащие введенное с клавиатуры слово. Вариант 27: предложения, содержащие числа.

3.(6 баллов) Варианты 1-20 – страницы 125-131 Практикума или 144-151 Учебника. Варианты 21-27 – задания для 10-17 вариантов соответственно. Необходимо выполнить следующие условия и решить следующие задачи:

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

Выполните задание из книги. Обратите внимание на первый пункт задания! Заполнение массива с клавиатуры выполнять не нужно (массив заполняется из файла), но не забудьте про сортировку.

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

Подготовлено Латухиной Е.А., старшим преподавателем кафедры ПиВВ ИМИКТ САФУ