我有一个"a b.c d.e"
格式的输入(不包括引号),我想解析成整数值,比如a1=a, a2=b, a3=c
,…等等。但技巧是"."
后面的值也可能丢失,因此,"a b d.e"
,"a b c"
,"a b.c d"
是有效的输入。但"a b. d.e"
无效,因为"b"
之后有一个"."
但后面没有数字。假设数字(如"a", "b"
等)是大于0小于1000的整数。
我只能想到做这件事的艰难方式。试过这个->
scanf("%d %2d[^. ].%2d[^. ] %2d[^. ].%2d[^\n]",&a,&b,&c,&d,&e);
但没用。我很感激使用
scanf()
参数技巧解析它。 最佳答案
如果我理解您对我的评论的回答,那么在本例中,我不认为您可以将输入压缩为scanf
格式字符串并处理您想要处理的变体。但是,在这种情况下,您可以回到tryed和true,解析任何内容,在strtol
的帮助下沿着字符串向下移动指针。strtol
提供一个结束指针,该指针在有效转换为输入字符串中的long
后设置为下一个字符。因此,如果您正在向下处理一个复杂的输入字符串,则从strtol (p, &ep, 10)
开始,其中p
是指向字符串的指针,ep
将设置为转换第一个数字后字符串中的下一个字符。(在您的情况下可以是a'.'
或' '
)。如果下一个字符是'.'
,则可以对后面的字符执行进一步的测试,并在逐个收集值时确定输入字符串是否有效。
在测试所需的条件并前进ep
以指向下一个要转换的有效数字的开头之后,只需设置p = ep;
并重复,直到填充a, b & c
或遇到错误条件为止。
当使用strtol
时,除了检查errno
之外,您还可以使用其他几个验证,但这对于本例就足够了。有关其余验证,请参见man strtol
。
如果我正确理解了你的逻辑,你可以做一些类似的事情:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define MAXC 32
int main (void) {
char buf[MAXC] = "", *p = buf, *ep = NULL;
int a = 0, b = 0, c = 0, tmp = 0;
printf ("enter values: ");
if (!fgets (buf, MAXC, stdin))
return 1;
for (;;) {
tmp = strtol (p, &ep, 10);
if (errno) { /* minimal conversion validation */
fprintf (stderr, "error: failed conversion.\n");
return 1;
}
if (!a) /* handle a */
a = tmp;
else if (!b) { /* handle b */
if (*ep && *ep == '.' && *(ep + 1) && *(ep + 1) == ' ') {
fprintf (stderr, "error: invalid input = '.' alone.\n");
return 1;
}
b = tmp;
if (*ep && *ep == '.' && *(ep + 1) &&
'0' <= *(ep + 1) && *(ep + 1) <= '9')
ep++;
else
while (*ep && (*ep < '0' || '9' < *ep))
ep++;
if (!*ep) {
fprintf (stderr, "error: invalid input - no 'c'.\n");
return 1;
}
}
else if (!c) { /* handle c */
if (*ep && *ep == '.' && *(ep + 1) &&
(*(ep + 1) == ' ' || *(ep + 1) == '\n')) {
fprintf (stderr, "error: invalid input = '.' alone.\n");
return 1;
}
c = tmp;
break;
}
p = ep;
}
printf ("a : %d\nb : %d\nc : %d\n", a, b, c);
return 0;
}
示例使用/输出
$ ./bin/triplet
enter values: 1 2.3 4.5
a : 1
b : 2
c : 3
$ ./bin/triplet
enter values: 1 2 3.4
a : 1
b : 2
c : 3
$ ./bin/triplet
enter values: 1 2 3
a : 1
b : 2
c : 3
$ ./bin/triplet
enter values: 1 2.3 4
a : 1
b : 2
c : 3
$ ./bin/triplet
enter values: 1 2. 3.4
error: invalid input = '.' alone.
仔细看一下,如果我误解了你的评论,请告诉我。如果不是,请记住您可以通过简单地将指针(或指针对)沿字符串向下移动来解析任何内容。
关于c - 重新解析C中的输入,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45251003/