Студопедия

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

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

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






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






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

 

Пример 11.3 Поиск вхождения слова в файле

 

#include " stdafx.h"

#include < iostream>

#include < fstream>

#include < string>

 

using namespace std;

 

int main()

{

setlocale(LC_ALL, " Russian");

 

const int len = 81;

char word[len], line[len], end_word[] = " done";

 

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

fstream f(" lab11.txt", ios:: in | ios:: out | ios:: trunc);

if (! f)

{

cout < < " Ошибка открытия файла" < < endl;

return -1;

}

 

//введем несколько строк для дальнейшего поиска в них

do

{

cin > > line;

//с файловым потоком можно работать как со стандартными cin и cout

f < < line < < endl;

}

//продолжаем пока не введем done

while (strcmp(line, end_word));

 

//сбросим файловый поток на начало

f.seekg(0);

 

cout < < " Содержимое файла: " < < endl;

 

//содержимое файла на экран

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

while (! f.eof())

{

f > > line;

cout < < line < < endl;

}

 

 

cout < < " Введите слово для поиска: ";

cin > > word;

 

//сбрасываем бит-признак конца файла eofbit

f.clear();

 

//сбросим файловый поток на начало

f.seekg(0);

 

//определим длину искомого слова

size_t l_word = strlen(word);

 

//счетчик вхождения слова

int wc = 0;

//читаем построчно и ищем слово word в строке

while (f.getline(line, len))

{

//поместим указатель p на начало строки

char *p = line;

//strstr возвращает указатель

// на элемент из строки p с которого начинается word

while (p = strstr(p, word))

{

//используем указатель не текущую позицию в строке

char *c = p;

 

//переместим p на символ сразу за концом слова

p += l_word;

 

//проверим стоит ли наше слово отдельно

//или это просто подстрока в другом (большем) слове

 

//проверим совпадает ли начало слова с началом строки

if (c! = line)

//проверим символ перед началом слова

//на принадлежность к разделителям

if (! ispunct(*(c-1)) & &! isspace(*(c-1)))

//начинается не с начала строки и

//не с разделителя => ищем дальше

continue;

 

//символы перед началом слова подходят

//проверяем символы за окончанием слова

//если это пробелы, символы пунктуации

//или конец строки => увеличиваем счетчик слов

if (ispunct(*p) || isspace(*p) || (*p == '\0'))

{

wc++;

cout < < " Слово найдено" < < endl;

}

}

}

 

cout < < " Количество вхождений слова: " < < wc < < endl;

 

return 0;

}

 

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

 

Пример 11.4 Поиск вхождения слова в файле с помощью strtok

 

#include " stdafx.h"

#include < iostream>

#include < fstream>

#include < string>

 

using namespace std;

 

int main()

{

setlocale(LC_ALL, " Russian");

 

const int len = 81;

char word[len], line[len], end_word[] = " done";

 

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

fstream f(" lab11.txt", ios:: in | ios:: out | ios:: trunc);

if (! f)

{

cout < < " Ошибка открытия файла" < < endl;

return -1;

}

 

//введем несколько строк для дальнейшего поиска в них

do

{

cin > > line;

f < < line < < endl;

}

//продолжаем пока не введем done

while (strcmp(line, end_word));

 

cout < < " Введите слово для поиска: ";

cin > > word;

 

//сбрасываем бит-признак конца файла eofbit

f.clear();

//сбросим файловый поток на начало

f.seekg(0);

 

//Список разделителей

char delims[] = ",.!? /< > |()*:; \" ";

 

//Указатель на начало слова

char *token;

 

//счетчик вхождения слова

int wc = 0;

//читаем построчно и ищем слово word в строке

while (f.getline(line, len))

{

//находим первый символ не из разделителей

//находим первый символ не из разделителей

token = strtok(line, delims);

 

//проверяем, остались ли еще слова

while (token! = NULL)

{

//strtok заменяет символ после разделителя

//на NULL поэтому можно сравнивать искомое и

//найденное слово

if (! strcmp(token, word))

wc++;

 

//Для поиска следующей лексемы в той же строке

//strtok необходимо передать NULL

token = strtok(NULL, delims);

}

}

 

cout < < " Количество вхождений слова: " < < wc < < endl;

 

return 0;

}

 

 

Пример 11.5 Произвольный доступ к файлу

 

// Открыть файл как двоичный сразу для ввода и вывода

// (создать новый, если отсутствует или перезаписать старый)

// Ввести элементы с клавиатуры

// Поменять знак четных элементов

 

#include " stdafx.h"

#include < iostream>

#include < fstream>

#include < iomanip>

 

using namespace std;

 

int main()

{

setlocale(LC_ALL, " Russian");

 

const int NP = 10;

const int IS = sizeof(int); //размер элемента int

 

int pt, i;

 

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

fstream fs(" random.txt",

ios:: binary | ios:: in | ios:: out | ios:: trunc);

if (! fs)

{

cerr < < " Ошибка открытия файла." < < endl;

return 1;

}

 

// Первоначальная запись файла.

cout < < " Начальные заняения: " < < endl;

for (i = 0; i < NP; i++)

{

pt = i;

//Приводим pt к типу char* для нормальной работы write

fs.write((char*)& pt, IS);

cout < < setw(4) < < pt;

}

 

cout < < endl < < endl;

 

// Чтение файла от конца к началу.

cout < < " Читаем из файла в обратном порядке: " < < endl;

for (i=0; i< NP; i++)

{

//Перемещаемся к i-му элементу с конца

fs.seekg(-(i + 1) * IS, ios:: end);

//Приводим pt к типу char* для нормальной работы read

fs.read((char*)& pt, IS);

cout < < setw(4)< < pt;

};

 

cout< < endl < < endl;

 

// Переписать четные индексы.

for (i=1; i< NP/2; i++)

{

//перемещаемся к i-му элементу

fs.seekg(2 * i * IS);

//читаем i-ый элемент

fs.read((char*)& pt, IS);

//меняем значение на противоположное

pt = -pt;

//возвращаемся на шаг назад, к только что прочитанному элементу

int p = fs.tellg();

p -= IS;

fs.seekg(p);

//перезаписываем его

fs.write((char*)& pt, IS);

}

 

//выводим файл на экран

cout < < " После перезаписи: " < < endl;

fs.seekg(0);

for (i=0; i< NP; i++)

{

fs.read((char*)& pt, IS);

cout < < setw(4) < < pt;

}

cout < < endl;

 

fs.close();

return 0;

}

 

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

 

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

1. Какие виды строк существуют в C++?

2. Как объявить C-строку?

3. Как осуществляется ввод-вывод строк?

4. Какие операции над строками вы знаете?

5. Перечислите операции над символами?

6. Перечислите стандартные потоки ввода-вывода?

7. Как создать файловый поток?

8. Какие режимы открытия файлов существуют?

9. Что такое двоичный режим ввода-вывода?

10. Что такое текстовый режим ввода-вывода?

11. Как осуществляется чтение символов и строк?

12. Как изменить текущую позицию в файле?

13. Как узнать текущую позицию в файле?

14. Для чего используется метод clear()?






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