我如何接受这样的输入:
a<b
b<c
也这样:
a<b,c
d<e
f<x,y,z
目前,我能够读取像
我对单个语句的代码是:
char a, b;
while(scanf("%c<%c\n", &a, &b) == 2)
/* Set alpha[0..26][0..26] to 1 */
alpha[a - 'a'][b - 'a'] = 1;
我对每行多个语句尝试了类似的方法:
char a;
while(scanf("%c<", &a)) {
char b;
while(scanf("%c,", &b)) {
if(getchar() == '\n') break;
/* Set alpha[0..26][0..26] to 1 */
alpha[a - 'a'][b - 'a'] = 1;
}
}
但是它不能满足我的要求。它卡在第一个while循环中。 我对scanf以及在C语言中读取输入不是很好。因此,请提供一些帮助。
答案 0 :(得分:2)
您可以使用getchar
来解决它。
关注code
可能会起作用:
#include <stdio.h>
#include <stdlib.h>
int main(){
int a;
int b;
char alpha[100][100];
while ((a=getchar()) != EOF) {
getchar(); // for <
while((b=getchar()) != '\n') {
/* Set alpha[0..26][0..26] to 1 */
alpha[a - 'a'][b - 'a'] = 1;
b = getchar();
if (b == ',')
continue;
else
break;
}
}
return 0;
}
答案 1 :(得分:0)
将每个表达式读取为字符串,然后使用sscanf()
和%n
模式对其进行解析,以获取解析部分的长度。 (请注意,%n
未被大多数C库视为转换。)
例如:
#include <stdlib.h>
#include <stdio.h>
#define STRINGIFY_(x) #x
#define STRINGIFY(x) STRINGIFY_(x)
#ifndef MAX_WORD_LEN
#define MAX_WORD_LEN 31
#endif
#define SCAN_WORD "%" STRINGIFY(MAX_WORD_LEN) "[^\t\n\v\f\r <,;]"
const char *parse(const char *spec,
void (*callback)(const char *less, const char *greater))
{
char less[MAX_WORD_LEN+1];
char more[MAX_WORD_LEN+1];
int len;
while (1) {
/* Skip an optional semicolon. */
len = -1;
if (sscanf(spec, " ; %n", &len) >= 0 && len > 0)
spec += len;
/* Try parsing the first pair. */
len = -1;
if (sscanf(spec, " " SCAN_WORD " < " SCAN_WORD " %n", less, more, &len) < 2 || len < 0)
break;
/* Report it. */
if (callback)
callback(less, more);
/* Scan additional right sides. */
spec += len;
while (1) {
len = -1;
if (sscanf(spec, " , " SCAN_WORD " %n", more, &len) < 1 || len < 0)
break; /* Only out of this inner while loop. */
/* Report this one too. */
if (callback)
callback(less, more);
spec += len;
}
}
/* Return a pointer to the first unparsed character. */
return spec;
}
将其应用于命令行上指定的每个表达式的示例程序:
void report(const char *left, const char *right)
{
printf(" %s < %s\n", left, right);
}
int main(int argc, char *argv[])
{
int arg;
const char *end;
for (arg = 1; arg < argc; arg++) {
printf("%s:\n", argv[arg]);
end = parse(argv[arg], report);
if (*end)
printf("but with '%s' not parsed.\n", end);
else
printf("completely parsed.\n");
}
return EXIT_SUCCESS;
}
如果将上面的内容编译为example
,然后运行
./example 'foo < bar foo < baz, war war < bar'
程序将输出
foo < bar foo < baz, war war < bar:
foo < bar
foo < baz
foo < war
war < bar
completely parsed.
也就是说,每个唯一对将调用一次回调函数(上面的report()
)。它接受“单词”作为名称,而不仅仅是单个字母。每个“单词”最多可以包含31个字符,并且可以包含除空格,<
,,
或;
之外的任何字符。
为了完整起见,它允许在子表达式之间使用分号,并忽略它们。
逻辑本身很简单。
首先,parse()
尝试扫描分号。周围的空白也会被跳过。
接下来,它尝试使用一对<
来扫描一对“单词”。如果失败,它将跳出无限循环,并返回指向第一个未解析字符的指针。如果表达式的语法正确,它将指向一个NUL字节(\0
)。
如果扫描了一对,则该对将调用回调函数(除非回调函数为NULL)。
接下来,一个内部循环尝试扫描逗号后跟“单词”。只要成功,就会为该对调用回调函数(使用原始的左侧,使用这个新的“单词”作为右侧)。否则,我们将跳出内循环,并开始新的外循环迭代。
因此,如果我们看foo < bar foo < baz, war war < bar
,那么foo < bar
将由外循环的第一次迭代进行解析; foo < baz
将由外部循环的第二次迭代解析,, war
由内部循环的解析;最后war < bar
将由最外层循环的第三次迭代进行解析。