调试有限状态机拼写检查器代码

发布于 2024-08-25 17:07:34 字数 1295 浏览 16 评论 0原文

我需要有人调试我在下面编写的 C++ 代码行,以便它可以运行。它的目的是使用状态到状态转换来检查单词“and”的拼写。

#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;
}

I need someone to debug the lines of c++ code I wrote below so it can run. It is intended to spell check the word "and" using state to state transition.

#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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

暮色兮凉城 2024-09-01 17:07:34

这是一个可用于测试代码的 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

Here's a C program that you could use to test your code:

// -*- 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;
}

Usage:

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

Output:

 Your keyword spelling is correct
0
以歌曲疗慰 2024-09-01 17:07:34

几点评论:

  • 定义FILE对象是不够的。您需要调用 fopen 来实际打开一个文件,然后才能使用 fscanf 或类似方法读取该文件。

  • strlen() 返回一个 size_t——无符号类型。它们使用 C 风格的空终止字符串。 std::string 是一个 C++ 字符串类。要使用 strlen 首先获取 C 样式字符串:

例如:

  strlen(in_str.c_str());
  • 通常,fstream 对象用于文件处理。

  • 不要使用全局对象,

  • error 函数未定义。

Few comments:

  • Defining the FILE object is not enough. You need to call fopen to actually open a file and only then can you read from it using fscanf or some such.

  • strlen() returns a size_t -- an unsigned type. They work with C-style null-terminated strings. std::string is a C++ string class. To use strlen get a C-style string first:

E.g:

  strlen(in_str.c_str());
  • Typically, fstream objects are used for file handling.

  • Instead of using global objects, try to pass around the information as arguments.

  • The error function is not defined.

写下不归期 2024-09-01 17:07:34
  1. 在使用函数之前必须定义它们。
  2. 没有定义名为 error exit、fscanf 和 strlen 的函数
  3. 未包含的库中
  4. 。 fscanf 还有一些参数,
  5. 对 EOF 的测试是错误的,请查看 fscanf 中的这一参数,

您可能需要将 -Wall 添加到编译指令中,以便将来自己查找所有缺陷。
此外,可以在互联网上轻松找到好的参考资料,例如 cplusplus.com

因为我今天感觉很慷慨:
对于状态机来说,开关与递归相结合是一个更加优雅的解决方案......

  1. You have to define your functions before you use them
  2. There is no function named error
  3. exit, fscanf, and strlen are defined in libraries that are not included.
  4. fscanf has a few more parameters
  5. the test on EOF is wrong, look into fscanf for this one

you might want to add -Wall to your compilation instruction to find all defects yourself in the future.
Also good reference material can be easily found on the internet, for instance cplusplus.com.

And because I'm feeling generous today:
A switch combined with recursion is a far more elegant solution for your state machine...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文