首先解释设计基础
通过状态划分来统计单词个数,这是为后面任务的完成做了铺垫
通过三种状态来判断指针的位置,从而达到计算是否未正确单词,是否有非法符号存在等情况。如果按照正确情况是,指针就会通过正常的状态变化从而计算单词数目
#define start 0
#define in_word 1
#define out_word 2
#define pointerror 3
//检测单词数目
struct words
{
int number;
int state;
};
words words_number(char *str)
{
words word;
word.number = 0;
if (str == NULL)
{
word.state =pointerror;
return word;
}
else
{
word.state = start;//正常单词
while (*str != '\0')
{
switch (word.state)
{
case start:
if (isalpha(*str))
{
word.state = in_word;
}
else
{
word.state = out_word;
}
break;
case in_word:
if (!isalpha(*str))//else keeping in_word
{
if (*str == ' ')
{
word.number += 1;
word.state = start;
}
else word.state = out_word;
}
break;
case out_word:
if (isalpha(*str)&&*(str-1)==' ')
{
word.state = in_word;
}//else keeping out_word
break;
}
str++;
}
}
return word;
}
准备阶段完毕,开始分割单词,并送入某个存储位置
需要知道的是我的英文长句的来源是从文件获取的,其次我的单词去路是通过函数指针传走的,如果你不需要传递到其他模块进行操作,那么也可以改为存放在某个位置
其次要明白的是,该操作是建立在上面单词计数的基础上完成的。可能与看官的思路不同,但是我想说明的是如何通过
状态变化的方式
从而达到我们需要的计数和分割操作。//函数指针
typedef void(*fun)(char *word);
//解析函数
void parse(char *file_name,fun fun_name);
#define start 0
#define in_word 1
#define out_word 2
void parse(char *file_name, fun fun_name)
{
FILE *fp = fopen(file_name, "r");
int i = 0;
if (fp != NULL)
{
char buffer[32] = { 0 };
char *p = buffer;
int state = start;//正常单词
while (!feof(fp))//判断文件 是否读到末尾,如果未读到末尾,则返回假,然后求反
{
char ch = fgetc(fp);
switch (state)
{
case start:
if (isalpha(ch))
{
*p = ch;
state = in_word;
}
else
{
state = out_word;
p--;
}
break;
case in_word:
if (!isalpha(ch))//else keeping in_word
{
if (ch == ' ')
{
state = start;
*p = '\0';
if (fun_name)
fun_name(buffer);
i++;
p = buffer;
p--;
}
else
{
state = out_word;
p = buffer;
p--;
}
}
else *p = ch;
break;
case out_word:
if (isalpha(ch) && *(p - 1) == ' ')
{
*p = ch;
state = in_word;
}//else keeping out_word
else p--;
break;
}
p++;
}
}
fclose(fp);
}