Как работать с файлом содержащим текст и даты?

Дан файл который содержит текст и даты. Нужно вывести в другой файл только те предложения которые содержат корректные даты (dd.mm.yy или dd.mm.yyyy) Как это стоит сделать?. Я не прошу делать мне задание, а прошу объяснить как его сделать.


Ответы (1 шт):

Автор решения: Павел Ериков

Написал примерно, как можно реализовать, то что вам нужно. (для маленького файла, который вмещается в 1024 байт рабочий код)

Функция нахождения предложения:

//Возвращает указатель на начало предложения
//и через ссылку размер предложения.
//Принимает строку
char* getNextSentence(char* str, int& size) {
    char* s = str;
    char* start;
    size = 0;
    //isDate = true если мы нашли цифру после, которой идет '.', что означает
    //что возможно мы нашли дату
    bool isDate = false;
    while (*s != '\0') {
        //Пропускаем все, что не латинские буквы
        while (*s != '\0' && !isLetter(*s)) ++s;
        //Сохраняем указатель на начало предложения
        start = s;
        //Подсчитыаем длину предложения. И учитываем то что в дате так же есть '.'
        while (*s != '\0' && (*s != '.' || isDate) && *s != '!' && *s != '?') {
            isDate = isNumber(*(s));
            ++s;
            ++size;
        }
        if (*s != '\0') {
            ++size;
            return start;
        }
    }
    return nullptr;
}

Функция, которая определяет есть ли в предложении дата:

//Возвращает true если предложение содержит дату, иначе false
//Принимает строку, начало которой является началом предложения
//и размер этого предложения
bool isWithDate(char* str, int size) {
    char* s = str;
    char* f = str + size;
    while (s < f) {
        //Доходим до первой цифры
        while (s < f && !isNumber(*s)) ++s;
        if (s < f && s + 7 < f) {
            //Проверяем последующие 7 символов по шаблону "dd.mm.yy" т.к. "dd.mm.yyyy" так же попадет под эту проверку
            if (isNumber(*(s + 1)) && (*(s + 2) == '.') && isNumber(*(s + 3)) && isNumber(*(s + 4))
                && (*(s + 5) == '.') && isNumber(*(s + 6)) && isNumber(*(s + 7))) 
                return true;
        }
        ++s;
    }
    return false;
}

Дополнительные функции:

bool isLetter(char s) {
return (s >= 'A' && s <= 'Z') ||
    (s >= 'a' && s <= 'z');
}

bool isNumber(char s) {
    return s >= '0' && s <= '9';
}

Функция main():

int main()
{
    ifstream input("D:\\input.txt", ios::in);
    if (!input) {
        cout << "Ошибка открытия файлa!";
        return -1;
    }
    ofstream out("D:\\output.txt", ios::out);

    const int buffer_size = 1024;
    char buffer[buffer_size];
    char* s;
    char* b = buffer;
    int size = 0;
    while (input.getline(buffer, buffer_size)) {
        s = getNextSentence(buffer, size);
        while (s != nullptr) {
            if (isWithDate(s, size)) {
                out.write((const char*)s, size);
                out << " ";
            }
            b = s + size;
            s = getNextSentence(b, size);
        }
    }

    input.close();
    out.close();
    return 0;
}

Сразу скажу код не идеален. Он всего лишь показывает примерную реализацию.

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

→ Ссылка