我想使用scanf()来读取特定格式的输入变量amout。
格式为(a1 | a2 | a3)& (a4 | a5)& (a6 | a7 | a8 | a9)#。
我希望scanf读取这种格式的所有内容。但是,他们的名字和名字可能会有所不同。
()&()的数量也可以变化。
可读的字符串是:
如何为此编写代码?
答案 0 :(得分:1)
以下是读取和解析行的基本设置。适应您的需求:
#define MAX_BUF 1024
void example(FILE *fpIn)
{
char buf[MAX_BUF];
while (fgets(buf, MAX_BUF, fpIn)>0) {
char *cp= buf;
while (*cp) {
if (isalpha(*cp)) {
// you have a variable
cp++; // update cp, then continue
continue;
}
else switch (*cp) {
case '(': // characters to skip or process, whatever you want
case ')':
case '|':
case ' ':
default:
//...
}
cp++;
}
}
}
答案 1 :(得分:0)
如果没有嵌套,这种语言是常规的,我们可以为它定义DFA。
我们可以写一个这样的正则表达式:
v = a[0+...+9]+
p = ( v[ | v]* )
。请注意,(
和)
是语言的一部分,[, ]
是仅作为正则表达式语法一部分的符号。e = p[ & p]*#
e = ( a[0+...+9]+[ | a[0+...+9]+]* )[ & ( a[0+...+9]+[ | a[0+...+9]+]* )]*#
此语言的DFA(缺少过渡到未显示的死区)看起来像
| 0,...,9
+-------+ +-----+
| | | |
( V a | V |
--->state0--->state1--->state2---+
^ |
| |
+----state3<-----+
& | )
| #
V
state4
每次转换到state2都表示当前变量名称的累积。转换到state1和state3表示当前变量名称的完成。因此,如果您实现此DFA,则可以在转换到state2时累积临时名称,并且可以在转出state2时完成临时名称。
input = "(a1|a2)&(a2|a3)#";
state = 0;
position = 0;
name = "";
while (position < n) {
if (state == 0) {
if (input[position] == '(') state = 1
else reject();
} else if (state == 1) {
if (input[position] == 'a') {
name = "a";
state = 2
} else reject();
} else if (state == 2) {
if (digit(input[position])) {
name = += input[position];
state = 2
} else if (input[position] == '|') {
display(name);
state = 1;
} else if (input[position] == ')') {
display(name);
state = 3;
} else reject();
} else if (state == 3) {
if (input[position] == '&') {
state = 1;
} else if (input[position] = '#') {
state = 4;
} else reject();
} else reject(); // no other states accept input
position++;
}
继续解析整个语言比你需要的更多,但它有一些很好的好处,比如告诉你输入格式是否合格以及将来如果你想用更复杂的东西做更容易扩展的话输入