input.txt
abc
#include <stdio.h>
#include <string.h>
//#include <ctype.h>
#define ERROR 3
// 状态机设计
// 0 行不用
// 0 列不用
//列查找按代号查询
// 代号是经过合并如123456789是数字合并为1 就是第一列
//延续状态机,改终止状态,当没有字符输入时,当前状态就是要进行判断的状态
//提示,可使用如下二维数组存储DFA。
//一个状态对应一行;一个输入符号(digit/other)对应一列。
//每看到输入字符串中一个符号,就以当且状态为行号,
//看到的符号为列号查询下个状态作为当前状态。
int integerDFA[][4] = {
// 符号,下个状态
// letter digit other
{0, 0, 0,0},
{0, 2,ERROR, ERROR}, // 状态1
{0, 2,2, ERROR}, // 状态2
{0, 0, 0} // 状态6
};
int statu; // 当前状态
int old_sta; // 上一个状态
FILE* fp;
FILE* fa2;
int lenth = 10000;
char* str = new char[1200]; // 循环读取文件,分200字节读取
char** cmd = new char*[lenth]; // 词元存储
int cnt = 0; // 分割词元个数
int isnum(char* p) {
if (*p >= '0' && *p <= '9') {
return 1;
}
return 0;
}
int isletter(char* p) {
if((*p>='a'&&*p<='z')||(*p>='A'&&*p<='Z')) {
return 1;
}
return 0;
// return isalpha(*p);
}
// 分割成单词
void splitv2(char *str) {
char* p = str;
int num = 0;
// 分割词语
// 按空格分割字符
while (*p != '\0') {
// printf("%c\n", *p);
if (*p == ' ' || *p == '\n') {
if (num != 0) {
cnt++;
num = 0;
}
} else {
cmd[cnt][num] = *p;
num++;
}
p++;
}
// 如果临时存储区字符不为0,说明还有分割字符,此时
// 恰好是最后一行时,或者到一行末尾了
if (*p == '\0') {
if (num != 0) {
cnt++;
num = 0;
}
}
}
//void check(char* str) {
int check(char* str) {
int checknum;
checknum = 2;
char*p = str;
// 进入字符探测,允许跳转状态
statu = 1;
old_sta = statu;
// 字符 '\0'也是比较对象,对应于状态机的非字符直接到结束状态。只有一个非字符就是结束符才能输出正确
do {
if(isletter(p)) {
checknum=1;
} else if(isnum(p)) {
checknum=2;
} else {
checknum=3;
}
statu = integerDFA[statu][checknum];
p++;
} while (*p != '\0');
printf("%d\n", statu);
if(statu==2) {
return 1;
}
return 0;
}
void init_cmd() {
for (int i = 0; i < lenth; i++) {
cmd[i] = new char[200];
}
// 分词存储先清空杂乱数据
for (int i = 0; i < lenth; i++) {
for (int j = 0; j < 200; j++) {
cmd[i][j] = '\0';
}
}
}
int main() {
fp = fopen("input.txt", "r");
fa2 = fopen("output.txt", "w");
init_cmd();
// 分割词语
// while (fgets(str, 200, fp) != NULL) {
// 利用scanf 读取吸收回车,而希冀里不能执行 '\n'的比较
while (fscanf(fp,"%s",str)!=EOF) {
// 处理回车,有些回车读取会影响代码结果
if (str[0] == '\n' && strlen(str) == 1) {
// printf("发现回车\n");
continue;
} else if (str[strlen(str) - 1 ] == '\n') {
// 发现文末回车
// printf("发现文末回车\n");
str[strlen(str) - 1 ] = '\0';
}
// 剥离成函数使用
splitv2(str);
}
// 对每个单词进行检查
// 这样解决不知道什么时候根据状态进行结束的问题。字符连续,没有字符了就根据状态给结论。
for (int i = 0; i < cnt; i++) {
printf("%s-----\n", cmd[i]);
// fprintf(fa2,"--%s--\n",cmd[i]);
if (check(cmd[i]) == 1) {
fprintf(fa2, "true\n");
} else {
fprintf(fa2, "false\n");
// fprintf(fa2,"%d\n",statu);
}
printf("%d\n",statu);
}
fclose(fa2);
fclose(fp);
return 0;
}