C语言编程;基于有限状态机程序的字符模式识别

C语言编程;基于有限状态机程序的字符模式识别,c,pointers,state-machine,C,Pointers,State Machine,我正在用C语言构建一个模式识别程序,它可以读取用户定义的字符串和用户定义的4个字符的模式。然后,该程序有一个函数来确定是否找到了模式以及模式(根据输入文本索引)最初是在哪里找到的 我知道这对你们大多数人来说都是基本的,我只是希望能很快成为一名更熟练的程序员。当我执行我的程序时,它以一种我不理解的方式陷入无限循环 我知道问题在于FindMatch函数,而不是输入文本和模式的读入。我的FindMatch函数有什么问题?!请帮忙 #include <stdio.h> #include &l

我正在用C语言构建一个模式识别程序,它可以读取用户定义的字符串和用户定义的4个字符的模式。然后,该程序有一个函数来确定是否找到了模式以及模式(根据输入文本索引)最初是在哪里找到的

我知道这对你们大多数人来说都是基本的,我只是希望能很快成为一名更熟练的程序员。当我执行我的程序时,它以一种我不理解的方式陷入无限循环

我知道问题在于FindMatch函数,而不是输入文本和模式的读入。我的FindMatch函数有什么问题?!请帮忙

#include <stdio.h>
#include <stdlib.h>

char *getCharBlock(int *size);
int findmatchA(char *text, char *pattern, int tsize, int psize);
void printIt(char *ptr, int index, int size);

int main(){
   char *text, *pattern; //pointers for the characters you will read
   char *p,*q,*r; //some pointer variables
   int tsize,psize,x,y,z; //some integers

   printf("Please input a sequence of character text (characters only will be stored):");
   text = getCharBlock(&tsize);

   printf(" Now input the pattern you seek to search for: ");
   pattern = getCharBlock(&psize);

   x = findmatch(text,pattern,tsize, psize);
   if(x== -1){
      printf("No Match Found \n");
      printf("No starting position for match exists \n");
   }
   else{
      printf("Match Has Been Found! \n");
      printf("Match starting position at index %d \n", x);
      printf("Remaining text after Match: \n");
      printIt(text, x+psize, tsize);
   }


   free(text);
   free(pattern);
}

char *getCharBlock(int *size){
   char *input = (char*) malloc (80*sizeof(char));
   char a;
   int i = 0;
   a = getchar();
   while(i<80 && a!= '\n'){

      if( (a>= 'a' && a <= 'z') || (a>= 'A' && a <= 'Z') ){
         *(input + i) = a;
         i++;
      }
      a = getchar();
   }
   *size = i;

   return input;
 }

 int findmatch(char *text, char *pattern, int tsize, int psize) {
   int index = 0;
   int state = 0;
   while (psize <= tsize) {

     if ((*(text + index) == *pattern) && state == 0){
         state = 1;
         index++;
          printf( "test 1 \n");
     }
     else if ((*(text + index) != *pattern) && state == 0){
          state = 0;
          index++;
          printf( "test1.1 \n");
     }
     else if (*(text + index) == *(pattern + 1) && state ==1) {
       state = 2;
       index++;
       printf( "test 2 \n");
     }
     else if (*(text + index) != *(pattern + 1) && state ==1) {
        state = 0;
        printf("test 2.2 \n");
     }
     else if (*(text + index) == *(pattern + 2) && state ==2) {
        state  = 3;
        printf("test 3 \n");
     }
     else if (*(text + index) != *(pattern + 2) && state ==2) {
        state  = 0;
        printf("test 3.3 \n");
     }
     else if (*(text + index) == *(pattern + 3) && state ==3) {
        state = 4;
        printf("test 4 \n");
     }
     else if (*(text + index) != *(pattern + 3) && state ==3) {
        state = 0;
        printf("test 4.4 \n");
     }
     else {
         return -1;
     }
     index++;
   }
   return index;
   }
#包括
#包括
char*getCharBlock(int*size);
int findmatchA(字符*文本,字符*模式,int tsize,int psize);
void printIt(字符*ptr,整数索引,整数大小);
int main(){
char*text,*pattern;//将要读取的字符的指针
char*p,*q,*r;//一些指针变量
int tsize,psize,x,y,z;//一些整数
printf(“请输入字符文本序列(仅存储字符):”;
text=getCharBlock(&tsize);
printf(“现在输入您要搜索的模式:”;
模式=getCharBlock(&psize);
x=findmatch(文本、图案、tsize、psize);
如果(x==-1){
printf(“未找到匹配项”);
printf(“不存在匹配的起始位置\n”);
}
否则{
printf(“已找到匹配项!\n”);
printf(“在索引%d\n”,x处匹配起始位置);
printf(“匹配后的剩余文本:\n”);
打印(文本,x+psize,tsize);
}
免费(文本);
自由(模式);
}
char*getCharBlock(int*size){
char*input=(char*)malloc(80*sizeof(char));
字符a;
int i=0;
a=getchar();

虽然(i='a'&&a='a'&&a我没有阅读您的全部代码,但我只关注您的无限循环问题

findmatch()函数中while循环的控制条件有问题。您正在检查psize中是否没有[x]。 数组可以被数组指针访问。所以状态[0]是数组中的第一个字符。状态==0,然后依次类推到状态==3,这很好,但需要处理数组。 我是诺布,不过差不多。 希望这会有所帮助

我知道这对你们中的大多数人来说都是基本的,我只是希望能尽快做到 成为一名更熟练的程序员

祝你好运,我给你提建议

有几个问题使程序无法正常运行

它以一种我不知道的方式陷入无限循环 明白

1) 您必须在此处执行以下操作:

`while (psize <= tsize) {`
这可能会妨碍正确的模式匹配

4) 未完成输入验证,例如:您应该确保模式的长度正好为
4
个字符

如果我只被允许给你一个建议,那就是:
“永远不要使用If-else链!”
。用
开关盒断开结构替换它

您的
int findmatch
就是一个完美的例子。如果else
链造成难以调试的丛林。您的状态非常相似,应该会产生和谐。
它们不是。您的函数可以替换为更简单的函数:

int findmatch(char *text, char *pattern, int tsize, int psize) { 
   int index = 0;
   int state = 0;       
   printf("Text=<%s> pattern=<%s> tsize=%d psize=%d \n",text, pattern, tsize, psize);
   while (index <= tsize) {

       switch (state)
       {
           case 0:
                state = next_state(text,pattern, "test 1", "test1.1", &index, 0, 1, 1);
            break;                
            case 1:  // pattern[0]          matched
                state = next_state(text, pattern, "test 2", "test2.2", &index, 1, 2, 0);
            break;
            case 2:  // pattern [0] [1]     matched
                state = next_state(text, pattern, "test 3", "test3.3", &index, 2, 3, 0);
            break;                
            case 3:  // pattern [0] [1] [2] matched
                state = next_state(text, pattern, "test 4", "test4.4", &index, 3, 4, 0);
            break;                
            case 4:
                printf("DONE, index = %d \n",index);
                return index;
            break;                
            default:
                printf("We should not be here! \n");
            break;
       } // case
   } // while       
   return -1;
}
intfindmatch(char*text,char*pattern,inttsize,intpsize){
int指数=0;
int state=0;
printf(“Text=pattern=tsize=%d psize=%d\n”,Text,pattern,tsize,psize);
而(索引<代码>#包括
#包括
int-Myindex=0;
char*getCharBlock(int*size);
int findmatchA(字符*文本,字符*模式,int tsize,int psize);
int findmatchB(字符*文本,字符*模式,int tsize,int psize);
int findmatchC(字符*文本,字符*模式,int tsize,int psize);
void printIt(字符*ptr,整数索引,整数大小);
int main(){
字符*text、*pattern、*text2、*pattern2、*text3、,
*pattern3;//要读取的字符的指针
char*p,*r;//一些指针变量
int tsize,psize,tsize2,psize2,tsize3,psize3,x,y,z;//一些整数
printf(“\n”);
printf(“请输入字符序列(只显示字符)”
“已存储):\n”);
text=getCharBlock(&tsize);
printf(“\n”);
//printf(“tsize是%d\n”,tsize);
printf(“现在输入要搜索的模式:\n”);
模式=getCharBlock(&psize);
//printf(“tsize为%d\n”,psize);
x=FindMatch(文本、图案、tsize、psize);
如果(x==-1){
printf(“\n”);
printf(“未找到匹配项”);
printf(“\n”);
printf(“不存在匹配的起始位置\n”);
}否则{
printf(“\n”);
printf(“已找到匹配项!!!\n”);
//printf(“%d\n”,x);
printf(“\n”);
printf(“在索引%d\n处匹配起始位置”,x-3);
printf(“\n”);
printf(“匹配后的剩余文本:\n”);
打印(文本、x、T尺寸);
}
////应该通过什么;
//查找匹配项,返回-1表示失败,或返回一个int,该int是要查找的索引
//匹配开始的位置。返回值可用于
//确定是否找到匹配项,以及在何处。
printf(“\n”);
printf(“现在输入非连续字符的字符文本序列”
“匹配(仅存储字符):\n”);
text2=getCharBlock(&tsize2);
printf(“\n”);
printf(“现在输入要在非连续模式中搜索的模式”
“方式:\n”);
模式2=getCharBlock(&psize2);
y=findmatchB(文本2、模式2、tsize2、psize2);
如果(y==-1){
printf(“\n”);
printf(“未找到匹配项”);
printf(“\n”);
printf(“不存在匹配的起始位置\n”);
}否则{
printf(“\n”);
printf(“已找到匹配项!!!\n”);
printf(“\n”);
printf(“在索引%d\n处匹配起始位置”,y-4);
printf(“\n”);
printf(“匹配后的剩余文本:\n”);
打印(文本、y、T尺寸);
}
printf(“\n”);
printf(“现在输入多个字符的字符文本序列”
“匹配(仅存储字符):\n”);
text3=getCharBlock(&tsize3);
printf(“\n”);
printf(“现在输入要搜索的模式:\n”);
pattern3=getCharBlock(&psize3);
z=FindMatch(文本3,模式
`while (psize <= tsize) {`
 else if (*(text + index) == *(pattern + 2) && state ==2) {
    state  = 3;             // sg! index++; is missing!
    printf("test 3 \n");
 }
 else if (*(text + index) != *(pattern + 2) && state ==2) {
    state  = 0;
    printf("test 3.3 \n");
 }
int findmatch(char *text, char *pattern, int tsize, int psize) { 
   int index = 0;
   int state = 0;       
   printf("Text=<%s> pattern=<%s> tsize=%d psize=%d \n",text, pattern, tsize, psize);
   while (index <= tsize) {

       switch (state)
       {
           case 0:
                state = next_state(text,pattern, "test 1", "test1.1", &index, 0, 1, 1);
            break;                
            case 1:  // pattern[0]          matched
                state = next_state(text, pattern, "test 2", "test2.2", &index, 1, 2, 0);
            break;
            case 2:  // pattern [0] [1]     matched
                state = next_state(text, pattern, "test 3", "test3.3", &index, 2, 3, 0);
            break;                
            case 3:  // pattern [0] [1] [2] matched
                state = next_state(text, pattern, "test 4", "test4.4", &index, 3, 4, 0);
            break;                
            case 4:
                printf("DONE, index = %d \n",index);
                return index;
            break;                
            default:
                printf("We should not be here! \n");
            break;
       } // case
   } // while       
   return -1;
}
#include <stdio.h>
#include <stdlib.h>

char *getCharBlock(int *size);
int findmatch(char *text, char *pattern, int tsize, int psize);
void printIt(char *ptr, int index, int size);

void printIt(char *ptr, int index, int size)
{
}

int main(void){
   char *text, *pattern;    // pointers for the characters you will read
   int tsize,psize,x;       // some integers

   printf("Please input a sequence of character text (characters only will be stored):\n");

   text = getCharBlock(&tsize);

   printf("Now input the pattern you seek to search for: \n");
   pattern = getCharBlock(&psize);

   x = findmatch(text, pattern, tsize, psize);

   if(x == -1){
      printf("No Match Found \n");
      printf("No starting position for match exists \n");
   }
   else{
      printf("Match Has Been Found! \n");
      printf("Match starting position at index %d \n", x - 4);
      printf("Remaining text after Match: <%s> \n", text + x );

      printIt(text, x+psize, tsize);
   }

   free(text);
   free(pattern);
}

char *getCharBlock(int *size){

   char *input = (char*) malloc (80*sizeof(char) +1 );
   if (input == NULL)
   {
       printf("No memory!\n");
       exit(-1);
   }

   char a;
   int i = 0;

   a = getchar();

   while( i<80 &&  a != '\n'){

      if( ((a>= 'a') && (a <= 'z'))  || ( (a>= 'A') &&  (a <= 'Z') ) ){

         * (input + i) = a;

         i++;
      }

      a = getchar();
   }

    * (input + i)  = 0; // sg7! terminate the string 

   *size = i;

   return input;
 }

int next_state(char *text, char *pattern, char *m1, char *m2, int *index, int patternInd, int next_state, int advInd )
{
    int state = 0;

    if (text[*index] == pattern[patternInd]){
        state = next_state;
        printf( "%s\n", m1);
        (*index)++;
    }
    else{
        printf( "%s\n", m2);
        if(advInd)
            (*index)++; 
    }
    return state;       
}

int findmatch(char *text, char *pattern, int tsize, int psize) {

   int index = 0;
   int state = 0;

   printf("Text=<%s> pattern=<%s> tsize=%d psize=%d \n",text, pattern, tsize, psize);
   while (index <= tsize) {

       switch (state)
       {
           case 0:
                state = next_state(text,pattern, "test 1", "test1.1", &index, 0, 1, 1);
            break;

            case 1:  // pattern[0]          matched
                state = next_state(text, pattern, "test 2", "test2.2", &index, 1, 2, 0);
            break;

            case 2:  // pattern [0] [1]     matched
                state = next_state(text, pattern, "test 3", "test3.3", &index, 2, 3, 0);
            break;

            case 3:  // pattern [0] [1] [2] matched
                state = next_state(text, pattern, "test 4", "test4.4", &index, 3, 4, 0);
            break;

            case 4:
                printf("DONE, index = %d \n",index);
                return index;
            break;

            default:
                printf("We should not be here! \n");
            break;
       } // case
   } // while

   return -1;
}
Please input a sequence of character text (characters only will be stored):                                                                   
aaabcdef                                                                                                                                      
Now input the pattern you seek to search for:                                                                                                
abcd                                                                                                                                          
Text=<aaabcdef> pattern=<abcd> tsize=8 psize=4                                                                                                
test 1                                                                                                                                        
test2.2                                                                                                                                       
test 1                                                                                                                                        
test2.2                                                                                                                                       
test 1                                                                                                                                        
test 2                                                                                                                                        
test 3                                                                                                                                        
test 4                                                                                                                                        
DONE, index = 6                                                                                                                               
Match Has Been Found!                                                                                                                         
Match starting position at index 2                                                                                                            
Remaining text after Match: <ef>                                                                                                              


Please input a sequence of character text (characters only will be stored):                                                                   
abcdefgh                                                                                                                                      
Now input the pattern you seek to search for:                                                                                                 
efgh                                                                                                                                          
Text=<abcdefgh> pattern=<efgh> tsize=8 psize=4                                                                                                
test1.1                                                                                                                                       
test1.1                                                                                                                                       
test1.1                                                                                                                                       
test1.1                                                                                                                                       
test 1                                                                                                                                        
test 2                                                                                                                                        
test 3                                                                                                                                        
test 4                                                                                                                                        
DONE, index = 8                                                                                                                               
Match Has Been Found!                                                                                                                         
Match starting position at index 4                                                                                                            
Remaining text after Match: <>  
#include <stdio.h>
#include <stdlib.h>
int Myindex = 0;
char *getCharBlock(int *size);
int findmatchA(char *text, char *pattern, int tsize, int psize);
int findmatchB(char *text, char *pattern, int tsize, int psize);
int findmatchC(char *text, char *pattern, int tsize, int psize);
void printIt(char *ptr, int index, int size);

int main() {
  char *text, *pattern, *text2, *pattern2, *text3,
  *pattern3; // pointers for the characters you will read
  char *p, *r;   // some pointer variables
 int tsize, psize, tsize2, psize2, tsize3, psize3, x, y, z; // some integers

  printf(" \n");
  printf("Please input a sequence of characters (only characters will be "
     "stored ): \n");
 text = getCharBlock(&tsize);
printf("\n");
// printf( "tsize is %d \n", tsize);
 printf(" Now input the pattern you seek to search for: \n");
 pattern = getCharBlock(&psize);
 // printf( "tsize is %d \n", psize);

 x = findmatchA(text, pattern, tsize, psize);
 if (x == -1) {
 printf("\n");
 printf("No Match Found \n");
 printf("\n");
 printf("No starting position for match exists \n");
} else {
printf("\n");
printf("Match Has Been Found!!! \n");
// printf( "%d\n", x);
printf("\n");
printf("Match starting position at index %d \n", x - 3);
printf("\n");
printf("Remaining text after Match: \n");
printIt(text, x, tsize);
}

 // //what should be passed?);
 // looks for a match, returns -1 for failure or an int which is the index to
// the location where the match starts.  the return values can be used to
// determine IF a match was found, and where.
printf("\n");
printf("Now input a sequence of character text for non-contiguous "
     "matching(characters only will be stored): \n");
text2 = getCharBlock(&tsize2);
printf("\n");
printf(" Now input the pattern you seek to search for in a non-contiguous "
     "manner: \n");
 pattern2 = getCharBlock(&psize2);

y = findmatchB(text2, pattern2, tsize2, psize2);
if (y == -1) {
printf("\n");
printf("No match found \n");
printf("\n");
printf("No starting position for match exists \n");
} else {
printf("\n");
printf("Match has been found!!! \n");
printf("\n");
printf("Match starting position at index %d \n", y - 4);
printf("\n");
printf("Remaining text after match: \n");
printIt(text, y, tsize);
}
printf("\n");
printf("Now input a sequence of character text for multiple "
     "matchings(characters only will be stored): \n");
text3 = getCharBlock(&tsize3);
printf("\n");
printf(" Now input the pattern you seek to search for: \n");
pattern3 = getCharBlock(&psize3);

z = findmatchC(text3, pattern3, tsize3, psize3);
printf("\n");
printf("The Number of Matches Is %d \n", z);

free(text);
free(pattern);
free(text2);
free(pattern2);
free(text3);
free(pattern3);
}

char *getCharBlock(int *size) {
// this would fill in the "string" of chars for the passed in char pointer.

char *input = (char *)malloc(80 * sizeof(char));
char a;
int i = 0;
a = getchar();
while (i < 80 && a != '\n') {

if ((a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z')) {
  *(input + i) = a;
  i++;
 }
  a = getchar();
}
*(input + i) = '\0';
*size = i;

return input;
}

int findmatchA(char *text, char *pattern, int tsize, int psize) {
 int index = 0;
 int state = 0;
  while (psize <= tsize) {

 if ((*(text + index) == *pattern) && state == 0) {
   state = 1;
   index++;
   //  printf( "test 1 \n");
 }

 else if ((*(text + index) != *pattern) && state == 0) {
   state = 0;
   index++;

   //  printf( "test1.1 \n");
  }

  else if (*(text + index) == *(pattern + 1) && state == 1) {
    state = 2;
    index++;
    //  printf( "test 2 \n");
   }

   else if (*(text + index) != *(pattern + 1) && state == 1) {
    state = 0;
    index++;

    //  printf("test 2.2 \n");
   }

   else if (*(text + index) == *(pattern + 2) && state == 2) {
    state = 3;
    index++;
    //  printf("test 3 \n");
    }

   else if (*(text + index) != *(pattern + 2) && state == 2) {
     state = 0;
     index++;

      //  printf("test 3.3 \n");
   }

   else if (*(text + index) == *(pattern + 3) && state == 3) {
    state = 4;
    index++;
    return index;
    //  printf("test 4 \n");
    break;
   }

  else if (*(text + index) != *(pattern + 3) && state == 3) {
    state = 0;
    index++;

    //  printf("test 4.4 \n");
    }

   else {
    return -1;
   }
  }
   return index;
 }

 int findmatchB(char *text2, char *pattern2, int tsize2, int psize2) { // non-
      //contiguous case
    int index = 0;
   int state = 0;

  while (psize2 <= tsize2) {

 if ((*(text2 + index) == *pattern2) && state == 0) {
   state = 1;
  index++;
  //  printf("test1\n");
  }

else if ((*(text2 + index) != *pattern2) && state == 0) {
  state = 0;
  index++;
  //  printf("test1.1\n");
}

else if (*(text2 + index) == *(pattern2 + 1) && state == 1) {
  state = 2;
  index++;
  //    printf("test2\n");
}

else if (*(text2 + index) != *(pattern2 + 1) && state == 1) {
  state = 1;
  index++;
  //    printf("test2.2\n");
}

else if (*(text2 + index) == *(pattern2 + 2) && state == 2) {
  state = 3;
  index++;
  //    printf("test3\n");
}

else if (*(text2 + index) != *(pattern2 + 2) && state == 2) {
  state = 2;
  index++;
  //  printf("test3.3\n");
}

else if (*(text2 + index) == *(pattern2 + 3) && state == 3) {
  state = 4;
  index++;
  //  printf("test4\n");
  break;
  return index;
}

else if (*(text2 + index) != *(pattern2 + 3) && state == 3) {
  state = 3;
  index++;
  //  printf("test4.4\n");
}

else {
  return -1;
 }
}
return index;
}

int findmatchC(char *text3, char *pattern3, int tsize3, int psize3) {
int index = 0;
int pindex = 0;
int state = 0;
int matchcount = 0;
// printf( "tsize is %d \n", tsize3);

while (index <= tsize3) {
//  printf( "test of inside loop \n");
// printf( "pindex is %d \n", pindex);
// printf( "tindex is %d \n", index);
// printf( " text value is %c \n", *(text3 + index));
// printf( " pattern value is %c \n", *(pattern3 + pindex));

 if (*(text3 + index) == *(pattern3 + pindex) && state == 0) {
  state = 1;
  index++;
  pindex++;
  //   printf( "test 1 \n");
  }

  else if (*(text3 + index) != *(pattern3 + pindex) && state == 0) {
  state = 0;
  index++;
  // pindex++;
  //   printf( "test1.1 \n");
  }

  else if (*(text3 + index) == *(pattern3 + pindex) && state == 1) {
  state = 2;
  index++;
  pindex++;
  // printf( "test 2 \n");
  }

  else if (*(text3 + index) != *(pattern3 + pindex) && state == 1) {
  state = 0;
  index++;
  //  pindex++;
  //   printf("test 2.2 \n");
  }

  else if (*(text3 + index) == *(pattern3 + pindex) && state == 2) {
  state = 3;
  index++;
  pindex++;
  //   printf("test 3 \n");
  }

  else if (*(text3 + index) != *(pattern3 + pindex) && state == 2) {
  state = 0;
  index++;
  //  pindex++;
  //   printf("test 3.3 \n");
  }

  else if (*(text3 + index) == *(pattern3 + pindex) && state == 3) {
  state = 0;
  index++;
  pindex = 0;
  matchcount++;
  //   printf("test 4 \n");

 }

  else if (*(text3 + index) != *(pattern3 + pindex) && state == 3) {
  state = 0;
  index++;
  pindex = 0;
  //   printf("test 4.4 \n");
  }

  else {
  return -1;
  }
 }

return matchcount;
}

 void printIt(char *ptr, int index, int size) {

  while (index < size) {
  printf("%c", *(ptr + index));
  index++;

   }
   printf("\n");
 }