Вывести предложения, содержащие заданное пользователем слово
Это должна быть программа, которая считывает текст из файла и выводит на экран только те предложения, которые содержат введенное пользователем слово. Как сделать так, чтобы при перезаписи предложений в файл output.txt каждое в новую строку, предложение считало разделителем не только точку, но и ! и ? И как сделать так, чтобы слово Dad, например, в начале предложения с заглавной буквы считалось одним и тем же словом с "dad" введенным с клавиатуры
#include <iostream>
#include <fstream>
using namespace std;
void copySentencesToFile(const char* inputFilename, const char* outputFilename) {
ifstream inputFile(inputFilename);
ofstream outputFile(outputFilename);
if (!inputFile.is_open() || !outputFile.is_open()) {
cerr << "Ошибка открытия файла" << endl;
return;
}
char sentence[200];
char ch;
int sentenceIndex = 0;
while (inputFile.get(ch)) {
if (ch == '.') {
sentence[sentenceIndex] = ch;
sentence[sentenceIndex + 1] = '\0'; // добавляем завершающий нулевой символ
outputFile << sentence << endl;
sentenceIndex = 0; // сбрасываем индекс для следующего предложения
}
else {
sentence[sentenceIndex] = ch;
sentenceIndex++;
}
}
inputFile.close();
outputFile.close();
}
int IsWordInSentence() {
char ch[256];
ifstream input("output.txt");
if (!input.is_open()) {
cout << "Невозможно открыть файл" << endl;
return 1;
}
char* a = new char[256];
cout << "Введите искомое слово: ";
cin.getline(a, 256);
int k = 0;
while (!input.eof()) {
input.getline(ch, 256);
if (strstr(ch, a)) {
cout << ch << endl;
k++;
}
}
if (k == 0) {
cout << "Такого предложения нет " << endl;
}
}
int main() {
setlocale(LC_ALL, "ru");
const char* inputFilename = "text.txt";
const char* outputFilename = "output.txt";
copySentencesToFile(inputFilename, outputFilename);
IsWordInSentence();
return 0;
}```
Ответы (1 шт):
предложение считало разделителем не только точку, но и ! и ?
Для этого можно добавить в условие проверки через оператор or сравнение со всеми знаками по мимо ch == '.'
Что же касается всего кода, его можно значительно улучшить с помощью STL контейнеров и библиотеки algorithm.
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
inline bool is_space(const char &c) {
return c == ' ';
}
inline bool is_sign(const char &c) {
return (c == '.') or (c == '!') or (c == '?');
}
inline bool is_sign_or_space(const char &c) {
return is_sign(c) or is_space(c);
}
int findSentencesWithFragment(const char *inputPath, const char *outputPath, const std::string &prompt) {
std::ifstream input(inputPath);
std::ofstream output(outputPath);
if (input.bad() or output.bad()) {
std::cout << "Невозможно открыть файл" << std::endl;
return 1;
}
// строка, содержащая в себе текст из входящего файла в кодировке UTF-8
std::string str(std::istreambuf_iterator<char>{input}, {});
// итератор на начало строки
auto it_begin = str.begin();
while (it_begin != str.end()) {
// find_if вернёт итератор либо на . ! ?, либо на str.end()
auto it_end = std::find_if(it_begin, str.end(), is_sign);
if (it_end != str.end()) {
// ищем слово в предложении
auto shift = std::string(it_begin, ++it_end).find(prompt);
// проверяем наличие слова в предложении и пробела после
if (shift != std::string::npos) {
// выводим в консоль предложение с найденным словом и записываем его в файл
std::cout << std::string(it_begin, it_end) << std::endl;
output << std::string(it_begin, it_end);
}
// пропускаем пробелы в начале предложения
it_end = std::find_if_not(it_end, str.end(), is_space);
}
it_begin = it_end;
}
return 0;
}
int main() {
// меняет кодировку cout на UTF-8, поддерживающий все языки мира
// проверьте кодировку выших файлов, она также должна быть UTF-8, иначе текст будет искажён
std::locale::global(std::locale("en_US.UTF-8"));
// к сожалению cin выдаст ASCII последовательность
// поэтому пока что обойдёмся поиском, заданным в коде
return findSentencesWithFragment("text.txt", "output.txt", "Фраза, слово или буква");
}
Правда в этой реализации не учитывается случай, когда слово в составе другого слова, но это также можно исправить при использовании std::find, где предикатом будет служить поиск слова с пробелом или символом на конце.