如何在使用sscanf时第二次匹配

问题描述 投票:2回答:1

我是C的新手,在C中使用sscanf()时遇到了问题。

我的代码提示用户输入几行数据。单个数据就像一个Python元组(1,3)或(-3,2),每行可能包含几个由零或多个空格分隔的“元组”,我的代码如下,

char buffer[100];

while(fgets(buffer, sizeof buffer, stdin) != NULL) {
    while(sscanf(&buffer, "%*[^0-9|-]%i%*[^0-9|-]%i", &key, &value) != 1) {
        break;
    }
    printf("key==%d, value==%d\n", key, value);
}

我使用fgets来读取用户输入的每一行,并使用sscanf来获取元组,但似乎sscanf无法匹配一行中的第二个元组(或者如何匹配)。为什么?还是有一些更明智的解决方案来解决我的问题?

c scanf fgets
1个回答
3
投票

%n说明符将给出扫描处理的字符数,并将其存储在int中。 累计偏移中的那些以遍历该行。 这个sscanf可以返回EOF,0,1或2.考虑使用== 2,因为你想要扫描两个整数。

char buffer[100];
int offset = 0;
int scanned = 0;
while ( fgets ( buffer, sizeof buffer, stdin) != NULL) {
    offset = 0;
    scanned = 0;
    while ( sscanf ( buffer + offset, "%*[^0-9|-]%i%*[^0-9|-]%i%n", &key, &value, &scanned) == 2) {
        offset += scanned;
        printf("key==%d,value==%d\n",key,value);
    }
}

如果%n不起作用,strchr可以用来找到(,sscanf(和两个整数,然后找到关闭的)。重复。 这使用@ WeatherVane建议的更简单的格式字符串。

char buffer[100];
char *begin = NULL;
char *end = NULL;
while ( fgets ( buffer, sizeof buffer, stdin) != NULL) {
    end = buffer;
    while ( begin = strchr ( end, '(')) {//get pointer to (
        if ( sscanf ( begin, "(%d ,%d", &key, &value) == 2) {//scan ( and two integers
            printf("key==%d,value==%d\n",key,value);
        }
        end = strchr ( begin, ')');//get pointer to )
        if ( ! end) {
            break;//did not find )
        }
    }
}

另一种策略可以使用strspnstrcspn

char buffer[100];
size_t begin = 0;
size_t count = 0;
while ( fgets ( buffer, sizeof buffer, stdin) != NULL) {
    begin = 0;
    while ( buffer[begin]) {// not zero
        count = strcspn ( &buffer[begin], "-0123456789");//count of non digit or -
        begin += count;
        if ( sscanf ( &buffer[begin], "%d ,%d", &key, &value) == 2) {//scan ( and two integers
            printf("key==%d,value==%d\n",key,value);
        }
        count = strspn ( &buffer[begin], " ,-0123456789");//count space , - or digit
        begin += count;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.