该程序可让您输入数学问题,例如:
Bob has 1 apple and Mike 2. What is the sum?
程序然后理解单词“sum”并将两个数字加在一起。至少这是我想要实现的目标。它不起作用,因为我得到非常大的数字。我怀疑表达式%d%s%d不够灵活,只有在问题为:
时才有效1 sum 2
订单似乎很重要。那么如何使其灵活,以便订单无关紧要?
#include <stdio.h>
#include <string.h>
int main() {
char question[100];
char buffer[100];
int result;
int n1, n2;
int operation;
printf ("Your mathematical question: ");
fgets(question, sizeof(question), stdin);
fflush(stdin);
if(strstr(question, "sum") || strstr(question, "add")){
operation = 0;
}
sscanf(question, "%d %s %d", &n1, buffer, &n2);
printf ("%d %d \n", n1, n2);
switch(operation) {
case 0: result = n1 + n2;
break;
}
printf ("%d", result);
return(0);
}
答案 0 :(得分:2)
尝试使用strtok
将输入字符串拆分为运算符和操作数列表。问题是,当表达数学短语时,诸如英语之类的自然语言没有正式的操作符和操作数顺序,而你的程序需要这样。
将输入拆分为运算符和操作数允许您按所需顺序匹配它们。
#include <stdio.h>
#include <string.h>
typedef enum
{
NO_OP,
ADDITION,
/* Add new operators here. */
} operator_t;
/* One operator plus two operands. */
#define NUMBER_OF_ITEMS 3
int main()
{
char question[100];
char buffer[100];
char *token;
int result = 0;
/* Extend this to allow more complex sentences with multiple operations. */
int operands[2];
int* nextOperand = &operands[0];
int itemCount = 0;
/* Turn this into an array to extend the parser. */
operator_t operator = NO_OP;
printf ("Your mathematical question: \r\n");
fgets(question, sizeof(question), stdin);
/* Tokens are seperated by SPACES in this example. */
const char delims[] = " ";
/* Get the first token. */
token = strtok(question, delims);
/* Walk through all tokens in the question string. */
while((token != NULL)&&(NUMBER_OF_ITEMS > itemCount))
{
/* use strcmp to avoid matches on words like 'summertime'. */
if((0 == strcmp(token, "sum")) || (0 == strcmp(token, "add")))
{
operator = ADDITION;
itemCount++;
}
else
{
/* Check that one integer can be parsed from the token. */
if(1 == sscanf(token, "%d", nextOperand))
{
nextOperand++;
itemCount++;
}
}
/* Find the next token. */
token = strtok(NULL, delims);
}
/* Perform the operation, if possible. */
if((NUMBER_OF_ITEMS == itemCount) && (NO_OP != operator))
{
switch(operator)
{
case ADDITION:
result = operands[0] + operands[1];
printf("The answer to your question (%d + %d) is %d.\r\n",
operands[0], operands[1], result);
break;
default:
printf("Oops, please ask my programmer to do some debugging.");
break;
}
}
else
{
printf ("I did not understand your question.\r\n");
}
}
请注意,您需要添加更多错误检查以获得良好的健壮性,但上面的代码应该有助于说明如何解决问题。
然后,您可以使用类似Reverse Polish Notation的内容来扩展解析器的功能。
答案 1 :(得分:0)
"%*[^0-9]%d%*[^0-9]%d"
之类的内容可能会有效,但这可能会使用sscanf()
。
格式说明符基本上是指“跳过,直到看到一个数字,转换一个十进制数,然后跳到下一个数字,最后转换另一个十进制数”。这当然假设输入不是以第一个数字开头,依此类推。
在依赖具有值的变量之前,您应该检查sscanf()
的返回值。