我有一个"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/

10-15 00:26
查看更多