Witam mam taki programik odpalam go w DOS-ie tak jak powinno sie i poprawny wzorzec wyswietla ale jak wpisze to algorytm wariuje i wywala dosa. Algorytm knutha- morrisa -pratta. Pobieranie ciagu znakow w ktorym mamy znalezc wzorzec jest odczytywane z pliku.
doszedlem do tego:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
void przesuniecie(char *wzorzec,int *tab);
int algKMP(char *wzorzec, char *tekst, int *T);
int fsize(FILE *fp);
int main(int argc, char *argv[])
{ FILE *input; /*Zmienna pliku*/
char odp; /*Zmienna ostatnio wciśniętego klawisza*/
char *tekst; /*Zmienna tekstu*/
char *wzorzec = (char*) malloc(sizeof(char)); /*Zmienna wzorca*/
if(argc<2)
{ printf("Nie podano pliku z danymi.");
getch();
exit(-1);
}
else if(argc<3)
{ printf("Nie podano wzorca.\nCzy chcesz podac wzorzec?[T/N]\n(wybranie opcji n spowoduje zakonczenie programu.):");
fflush(stdin); /*Wyczyszczenie bufora wejścia*/
odp = getche(); /*Pobranie znaku*/
printf("\n");
while(!(odp=='T' || odp=='t' || odp=='N' || odp=='n')) /*Dopóki odpowiedź jest spoza zakresu wczytaj ponownie*/
{ printf("Podano odpowiedź spoza zakresu. Prosze wprowadzic ponownie [T/N]:");
fflush(stdin);
odp = getche();
printf("\n");
}
if(odp=='T' || odp=='t')
{ printf("Prosze podac wzorzec:"); /*Wczytanie wzorca*/
*wzorzec=0;
char zmpom = getch(); /*Zmienna pomocnicza pierwszego znaku*/
printf("%c",zmpom);
int i=1; /*Zmienna pozycji znaku wzorca*/
do
{ fflush(stdin);
odp = getch();
printf("%c",odp); /*Do dodania obsługa backspace i delete ...*/
*(wzorzec+i)=odp;
*wzorzec = (char *) realloc(0,(++i)*sizeof(char));
*(wzorzec+i)=0;
}while(odp!=13); /*Dopóki nie pojawi się enter (ASCII 13)*/
*wzorzec=zmpom; /*Zapisujemy pierwszy znak, który był nadpisywany*/
*(wzorzec+i-1)=0; /*I zamieniamy enter na znak zerowy*/
printf("\n");
}
else
{ exit(0); /*W przypadku wybrania opcji nie - wyłączam program*/
}
}
else
{ *wzorzec = (char *) malloc(sizeof(argv[2])); /*Jeżeli podano trzeci argument - zapisz jako wzorzec*/
strcpy(wzorzec,argv[2]);
}
input = fopen (argv[1],"r"); /*Otwieram plik do odczytu*/
if (input == NULL)
{ printf("Blad odczytu pliku : ");
perror (NULL); /*Jeżeli plik nie zostanie otworzony drukuje błąd*/
system("pause");
exit (-2); /*i wyłączam program po naciśnięciu dowolnego klawisza*/
}
else
{ tekst =(char *) malloc(fsize(input)*sizeof(char)); /*Alokujemy pamięć na tekst*/
fgets(tekst, fsize(input), input); /*i go pobieramy*/
}
int ile,i;
int * result;
result = (int *) malloc(sizeof(int)); /*inicializacja tablicy wyników*/
ile = algKMP(wzorzec,tekst,result);
int j=strlen(tekst); /*Zmienna dlugosci tekstu*/
int k=strlen(wzorzec); /*zmienna dlugosci wzorca*/
int rn=1; /*Zmienna aktualnego wyniku*/
HANDLE uchwyt=GetStdHandle(STD_OUTPUT_HANDLE); /*Uchwyt konsoli*/
i=0;
do
{ for(;i<*(result+rn);i++) printf("%c",*(tekst+i)); /*Drukujemy aż do miejsca wystąpienia wyniku*/
SetConsoleTextAttribute(uchwyt,12); /*Zmieniamy kolor tekstu*/
for(;i<*(result+rn)+k;i++) printf("%c",*(tekst+i)); /*Drukujemy wynik*/
SetConsoleTextAttribute(uchwyt,7); /*Zmieniamy kolor tekstu*/
rn++;
}while(rn<=ile);
for(;i<j;i++) printf("%c",*(tekst+i));
getch();
}
void przesuniecie(char *wzorzec,int *tab)
{ int len=strlen(wzorzec); /*Zmienna długości wzorca*/
*(tab)=-1;
*(tab+1)=0;
int i,j=0; /*Zmienna iteracji i pozycji początku tekstu*/
for(i=2;i<len;i++) /*Dopóki nie dotrę do końca wzorca*/
{ if(*(wzorzec+i)==*(wzorzec+j)) *(tab+i)=++j; /*a sprawdzana pozycja zgadza się z początkiem + j*/
else /*inkrementuje j i wpisuje je do tablicy przesunięc*/
{ j=0; /*W przeciwnym wypadku zeruje j i do tablicy wpisuję 0*/
*(tab+i)=0;
}
}
}
int algKMP(char *wzorzec, char *tekst, int *T)
{ int wlen = strlen(wzorzec); /*Zmienna długości wzorca*/
int tlen = strlen(tekst); /*Zmienna długości tekstu*/
int *przes =(int *) malloc(wlen*sizeof(int)); /*Tablica przesunięć*/
int ile=1; /*Zmienna ilości wyników*/
przesuniecie(wzorzec,przes); /*Wyznaczenie tablicy przesunięć*/
int i,j=0; /*Zmienne numeru iteracji i pozycji znakowej wzorca*/
for(i=0;i<tlen;)
{ if(*(wzorzec+j)==*(tekst+i) && j<wlen-1) /*Znaleziono kolejny znak zgodny z wzorcem*/
{ j++;
i++;
}
else if(*(wzorzec+j)==*(tekst+i) && j==wlen-1) /*Znaleziono poszukiwany wyraz*/
{ *T = (int *) realloc(0,(ile+1)*sizeof(int)); /*Realloc zamazuje pierwszy wynik, więc zapisuje w
tablicy numerowanej od 1 i alokuje dodatkowe miejsce.*/
*(T+ile)=i-wlen+1; /*Zapisanie pozycji wyrazu*/
ile++;
j=0;
i++;
}
else
{ i-=*(przes+j); /*Nie znaleziono zgodności znaku z wzorcem*/
j=0;
}
}
return ile-1; /*Zwracamy ilość znalezionych powtórzeń wzorca*/
}
int fsize(FILE *fp) /*Znalezione - http://stackoverflow.com/questions/238603/how-can-i-get-a-files-size-in-c*/
{ int prev=ftell(fp); /*Początek pliku*/
fseek(fp, 0L, SEEK_END); /*Szukamy końca*/
int sz=ftell(fp); /*Zapisujemy numer ostatniego znaku w pliku*/
fseek(fp,prev,SEEK_SET); /*Wracamy na początek pliku*/
return sz+1; /*Zwracamy długość pliku*/
}