Вывод предложений из файла на C++

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Disite77
Сообщения: 1
Зарегистрирован: 19 янв 2016, 14:00

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

Код: Выделить всё

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <conio.h>
 
using namespace std;
char *filetr="C:\\text.txt";
void ReadFile()
{
    string s;
    int end,begin=0,pos;
    ifstream fileStream(filetr);
    while (!fileStream.eof())
        {
     getline(fileStream,s);//Построчное считывание информации в S
      while(1){
        end = s.find('.',begin); // поиск окончания предложения
        if( end == string::npos ) break; // если предложений нет
        pos = s.find( '4', begin ); // поиск цифрового символа
        if( pos < end ) // если в текущем предложении есть цифра
            cout.write( &s[begin], end-begin +1 ) << "\n"; // вывод предложения
        begin = end+1; // начало нового предложения
              }
        }
       fileStream.close();  //Закрыли открытый файл
}
int main()
{ setlocale(LC_ALL,"Russian");
    ReadFile();
   getch();
}
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Ошибки:

1. Переменная begin выставляется в ноль до начала цикла по строкам. Так что для первой строки файла всё будет работать, а для второй уже не будет, так как begin не будет сброшена в ноль. Переменную нужно сбрасывать в начале каждой итерации внешнего цикла.

2. После поиска цифры нет проверки на то, что цифра не найдена (проверка на string::npos). А по тому условию, которое написано, будет получаться, что если цифра не найдена, то алгоритм будет делать вывод, что она как раз найдена (ведь npos это -1, а -1 в любом случае меньше end).

Дополнительные замечания:

Чтобы приблизить алгоритм к тому, что требуется в задании, нужно искать не только '4', а любые цифровые символы, верно? Рекомендую вместо find использовать find_first_of. В этот метод можно скормить строку и метод будет искать любой из встреченных в ней символов.

Есть ещё один интересный вопрос. Может ли предложение быть размещено на нескольких строках? Если да, то алгоритм нужно поправить. Нужно сделать два отдельных цикла. В первом мы построчно читаем строки и аккумулируем их в переменной типа std::string, выбрасывая переводы кареток. А во втором цикле (который будет не внутри, а после первого) уже обходим получившуюся громадную строку и ищём в ней точки.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

2. После поиска цифры нет проверки на то, что цифра не найдена (проверка на string::npos). А по тому условию, которое написано, будет получаться, что если цифра не найдена, то алгоритм будет делать вывод, что она как раз найдена (ведь npos это -1, а -1 в любом случае меньше end).
А для чего вообще понадобился знаковый индекс символа в строки, чьи символы индексируются с ноля? Надо просто объявить begin, pos и end типа size_t, тогда индекс не найденного символа будет максимально представимым и заведомо не сможет быть строго меньше чего либо.
Есть ещё один интересный вопрос. Может ли предложение быть размещено на нескольких строках? Если да, то алгоритм нужно поправить. Нужно сделать два отдельных цикла. В первом мы построчно читаем строки и аккумулируем их в переменной типа std::string, выбрасывая переводы кареток. А во втором цикле (который будет не внутри, а после первого) уже обходим получившуюся громадную строку и ищём в ней точки.
Зачем? Это можно сделать в одном и том же цикле. Всё равно ведь предыдущее предложение или уже выведено, или в нём нет цифр, а значит его уже не нужно хранить. И мало того, туда же свалить проверку текущего символа на то, что это цифра. Встретилась точка - проверяем флаг того, что были цифры, если установлен, то выводим строку, потом в любом случае очищаем. Проблема будет только в многоточии, вопросительных и восклицательных знаках в скобках, в цитатах и в дробных числах с точками.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Сионист писал(а):А для чего вообще понадобился знаковый индекс символа в строки, чьи символы индексируются с ноля? Надо просто объявить begin, pos и end типа size_t, тогда индекс не найденного символа будет максимально представимым и заведомо не сможет быть строго меньше чего либо. Зачем? Это можно сделать в одном и том же цикле. Всё равно ведь предыдущее предложение или уже выведено, или в нём нет цифр, а значит его уже не нужно хранить. И мало того, туда же свалить проверку текущего символа на то, что это цифра. Встретилась точка - проверяем флаг того, что были цифры, если установлен, то выводим строку, потом в любом случае очищаем. Проблема будет только в многоточии, вопросительных и восклицательных знаках в скобках, в цитатах и в дробных числах с точками.
Это сообщение вообще не осилил.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ответить