2010-03-13 49 views
0

我需要某人來調試我寫在下面的C++代碼行,以便它可以運行。它旨在拼寫檢查單詞「和」使用狀態到狀態轉換。調試有限狀態機拼寫檢查代碼

#include<iostream> 
#include<string> 

using namespace std; 

string in_str; 
int n; 
void spell_check() 
{ 
    int i; 
    FILE *in_file; 

    while (!EOF(in_file)) 
    { 
      fscanf(in_str); 
      n = strlen(in_str); 
      start(in_str,n); 
    } 
} 

void start() 
{ 
    char next_char; 

    int i = 0; 
    if (n == 0) 
    { 
      cout<<"This is an empty string"; 
      exit();//do something here to terminate the program 
    } 
    else{ 
      next_char = in_str[i]; 

      if(next_char == 'a') 
      { 
         i++; 
         if(i >= n) error(); 
         else state_A(i); 
      } 
      else error(); 
    } 
} 

void state_A(int i) 
{ 
    if(in_str[i] == 'n') 
    { 
        i++; 
        if(i<n) state_AN(i); 
        else error(); 
    } 
    else error(); 
} 

void state_AN(int i) 
{ 
    if(in_str[i] == 'd') 
    { 
        if(i == n-1) 
         cout<<" Your keyword spelling is correct"; 
        else 
         cout<<"Wrong keyword spelling"; 
    } 
} 

int main() 
{ 
    spell_check(); 
    return 0; 
} 
+0

我個人會將啓動函數state_,state_start或state_0命名爲更加一致。 – NomeN 2010-03-13 02:07:48

+0

Durell,當你發佈它時,我沒有看到問題。你遇到的實際問題是什麼? – 2010-03-13 02:54:59

+0

@gf看到他的代碼(不)編譯,它正在解釋和解決簡單的編譯器警告... – NomeN 2010-03-13 03:19:08

回答

0

幾點意見:

  • 定義FILE對象是不夠的。您需要致電fopen實際打開一個文件,然後纔可以使用fscanf或其他類似文件讀取它。

  • strlen()返回一個size_t - 一個無符號類型。他們使用C風格的以null結尾的字符串。 std::string是一個C++字符串類。要使用strlen首先得到C風格的字符串:

E.g:

strlen(in_str.c_str()); 
  • 通常情況下,用於文件處理fstream對象。

  • 而不是使用全局對象,嘗試傳遞信息作爲參數。

  • error函數未定義。

0
  1. 您必須在使用它們
  2. 之前並沒有一個名爲錯誤
  3. 退出,的fscanf和strlen的中未包含庫定義的功能來定義的功能。
  4. 的fscanf有幾個參數
  5. 上EOF測試是錯誤的,考慮的fscanf這一個

你可能想-Wall添加到您的編譯指令給自己找到所有的缺陷在未來。 在互聯網上也可以很容易地找到好的參考資料,例如cplusplus.com

而且因爲我今天感覺大方:
開關與遞歸相結合是你狀態機更優雅的解決方案......

1

這裏,你可以用它來測試你的代碼一個C程序:

// -*- coding: utf-8 -*- 
#include <stdio.h> 
#include <stdlib.h> // EXIT_* 

#define log(msg) do { \ 
    puts(msg); \ 
    } while(0) 

/** $ graph-easy --input=fsm.dot --as=boxart 

     ┌─────────────────────────────────────────┐ 
     │           │ 
     │    [^a]      │ 
     │  ┌───────────────────┐    │ 
     │  ▼     │    │ 
     │  ╔═══════╗ [^a] ╔════╗   │ 
     │  ║  ║ ───────┐ ║ ║   │ 
     │  ║ START ║  │ ║ O ║   │ a 
     └──── ║  ║ ◀──────┘ ║ ║ ─┐  │ 
       ╚═══════╝   ╚════╝ │  │ 
       │     │  │  │ 
       │     │ a │  │ 
       │     ▼  │  │ 
       │     ╔════╗ │  │ 
       │  ┌─────── ║ A ║ ◀┼───────┘ 
       │  │  ╚════╝ │ 
       │  │   │  │ 
       │  │   │ n │ 
       │  │   ▼  │ 
       │  │  ╔════╗ │ 
       │  │  ║ N ║ ─┼───────┐ 
       │  │  ╚════╝ │  │ 
       │  │   │  │  │ 
       │  │   │ d │  │ 
       │  │   ▼  │  │ 
╔═════╗ EOS  │  │  ╔════╗ │  │ 
║ END ║ ◀────────┼────────┼─────── ║ D ║ │  │ 
╚═════╝   │  │  ╚════╝ │  │ 
       │  │   │  │  │ 
       │  │ [^n]? │ . │ EOS │ [^d]? 
       │  │   ▼  ▼  ▼ 
       │  │  ╔══════════════════════╗ 
       │  └──────▶ ║      ║ 
       │     ║  ERROR   ║ 
       │  EOS  ║      ║ 
       └───────────────▶ ║      ║ 
            ╚══════════════════════╝ 
*/ 
typedef enum State { 
    O, START, A, N, D, ERROR 
} State; 

static int next_token(void) { 
    int ch = getchar(); 
    if (ch == '\n') // consider newline as EOS 
    return EOF; 
    return ch; 
} 

static int spell_check(void) { 
    State state = O; 
    int token = -1; 
    while ((token = next_token()) != EOF) { 
    switch(state) { 
    case START: 
     log("I am comming"); 
     // fall through 
    case O: 
     state = token == 'a' ? A : START; break; 
    case A: 
     state = token == 'n' ? N : ERROR; break; 
    case N: 
     state = token == 'd' ? D : ERROR; break; 
    case D: 
     state = ERROR; break; 
    case ERROR: 
     return EXIT_FAILURE; 
    default: 
     log("can't happen"); 
     return EXIT_FAILURE; 
    } 
    } 
    if (state == O) 
    log("This is an empty string"); 
    return state == D ? EXIT_SUCCESS : EXIT_FAILURE; 
} 

int main(void) { 
    int rc = spell_check(); 
    if (rc == EXIT_SUCCESS) 
    log(" Your keyword spelling is correct"); 
    else 
    log("Wrong keyword spelling"); 
    return rc; 
} 

用法:

$ gcc *.c && (echo and | ./a.out; echo $?) 

輸出:

Your keyword spelling is correct 
0 
+0

留下他的想象力的人的東西......這是一個作業問題。 – NomeN 2010-03-13 14:02:33

+0

@NomeN:OP的作業是使用遞歸實現來編寫fsm。我的版本顯然是非遞歸的。它可以用於測試目的。 – jfs 2010-03-13 16:44:21

+0

@ J.F。塞巴斯蒂安OP在他的文章中沒有提及遞歸。儘管在我的回答中,我試圖指向他,也許你從那裏精神上撿起來了? – NomeN 2010-03-13 17:28:50