#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
//Функция читает файл pName в буфер *pBuffer
//Возвращает длину буфера, если ошибка, то вернет 0
//После использования необходимо освободить буфер при помощи free
int ReadFromFile(char ** pBuffer, char * pName)
{
HANDLE hFile;
DWORD len, lenhi;
if ((hFile = CreateFile(pName, GENERIC_READ, NULL, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
{
printf ("File '%s' not found\n",pName); //ошибка - файл не найден
return 0;
}
len = GetFileSize(hFile, &lenhi); //длина файла
*pBuffer = (char*)malloc(len); //запросим память в куче
//Читаем файл в буфер
if (ReadFile(hFile, *pBuffer, len, &lenhi, NULL) && len==lenhi)
{
CloseHandle(hFile); //Все ок - закроем файл
return len; //И вернем длину файла/буфера
}
else
{
printf ("Read error of file '%s'\n",pName); //ошибка чтения
CloseHandle(hFile); //закроем файл
free(pBuffer); //освободим буфер
return 0; //признак ошибки
}
}
//Функция считает количество совпадений образца с данными из буфера
//Параметры: pFile - указатель на буфер данных из файла
// len - длина буфера данных
// pStr - указатель на строку образца
// lenStr- длина строки образца
//Возвращает число совпадений
int GetCount(char * pFile, int len, char * pStr, int lenStr)
{
int i; //индекс в буфере данных
int j; //индекс в буфере
int k; //переменная для сохранения позиции в буфере данных
int m; //счетчик для анализа по *
int count; //количество совпадений
for (count=m=i=0; i<len;) //начало поиска очередного совпадения
{
//здесь крутимся, пока не пройдем строку образца (т.е. найдем очередное совпадение)
//либо дойдем до конца
for (j=0; j<lenStr && i<len; j++,i++)
{
if (j==0) //в начале анализа запомним позицию,
k=i; // чтобы иметь возможность корректного продолжения анализа
switch (pStr[j]) //анализируем символы образца
{
case '+': //просто идем дальше
break; // устраивает любой символ
case '*':
if (j != (lenStr-1)) //если * - последний символ в строке образца, то * как +
{
m+=5; //иначе разрешаем еще любые из 0-5 символов
i--;
}
break;
default: //если символы равны, то идем дальше
if (pStr[j] != pFile[i]) //если не равны
{
if (m>0) //для * разрешаем m отличных символов
{
j--; //чтобы сравнивать с тем же символом из образца (+1 добавится в цикле)
m--; //уменьшим число разрешенных отличных символов
}
else //для обычного сравнения начинаем сравнения с начала образца
{
j=-1; //на начало строки образца (+1 добавится в цикле)
i=k; //восстановим индекс (+1 добавится в цикле)
}
}
}
}
//цикл пройден, но надо исключить возможность, когда вышли из цикла по концу данных,
// хотя полного совпадения не было
if (j>=lenStr) //если сравнение пройдено полностью
count++; // то инкременируем счетчик совпадений
}
return count;
}
int main(int argc, char* argv[])
{
char str[256]; //буфер для ввода образца
char *pStr; //указатель строку образца
char *pFile; //указатель на буфер для данных из файла
int len; //длина файла
len = ReadFromFile(&pFile, "input.txt"); //прочитаем файл
if (len) //продолжаем работу только если все ок
{
str[0] = (char)254; //максимальный размер буфера для ввода строки образца
while (1) //бесконечный цикл анализа
{
printf ("Enter pattern: "); //прилашение к вводу образца
pStr = _cgets(str); //вводим образец
if (0==str[1]) //если длина строки = 0
break; // то выходим из цикла и завершаем работу
//считаем и выводим
printf("Count = %d\n", GetCount(pFile, len, pStr, str[1]));
}
free(pFile); //освобождаем буфер
}
return 0;
}