Как работать с файлом содержащим текст и даты?
Дан файл который содержит текст и даты. Нужно вывести в другой файл только те предложения которые содержат корректные даты (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 байт тут уже я не придумал, что делать.