以特定格式使用sscanf

时间:2017-08-16 16:28:01

标签: c

我正在尝试使用带有完全符合以下格式的字符串的sscanf:

  

integer1 integer2

这样我就可以将int1和int2存储到数组

我希望sscanf检查是否只输入两个数字,只分隔一个空格,根本没有前导或尾随空格。 应该和不应该起作用的例子:

应该

4 7

应该不是

   4 7
4 7[WHITESPACE] 
4    7
4 7a

我一直试图以下列方式使用它

sscanf(str,"%d %d",&value1,&value2);

if (*STRING CONTAINS INVALID CHARACTERS OR WHITESPACE*){
    exit from parent function }

1 个答案:

答案 0 :(得分:1)

如果你只处理没有前导符号的正整数,这里有一个更简单的解决方案:

#include <stdio.h>
#include <string.h>

int validate_string(const char *buf, int *int1, int *int2) {
    size_t len1, len2;
    /* return non 0 if and only if line has the correct format
       and int1 and int2 contain the converted numbers */
    return (len1 = strspn(buf, "0123456789")) > 0
    &&     buf[len1] == ' '
    &&     (len2 = strspn(buf + len1 + 1, "0123456789")) > 0
    &&     buf[len1 + len2 + 1] == '\0'
    &&     sscanf(buf, "%d%d", int1, int2) == 2);
}

但请注意,此解决方案无法充分测试数字转换中的潜在溢出。

以下是strtol()

的替代方案
#include <ctype.h>
#include <stdlib.h>

int parse_int(int *dest, const char *buf, char **pp)
int validate_string(const char *buf, int *int1, int *int2) {
    char *p1, *p2;
    return !isspace((unsigned char)*buf)
    &&     ((*int1 = strtol(buf, &p1, 10)), p1 > buf)
    &&     *p1++ == ' '
    &&     !isspace((unsigned char)*p1)
    &&     ((*int2 = strtol(p1, &p2, 10)), p2 > p1)
    &&     *p2 == '\0');
}

修改以避免chux提交的实现定义的行为:

#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>

int parse_int(int *dest, const char *buf, char **pp) {
    long val;
    if (isspace((unsigned char)*buf)
        return 0;
    val = strtol(buf, pp, 10);
    if (*pp <= buf)
        return 0;
    if (val < INT_MIN) {
        val = INT_MIN;
        errno = ERANGE;
    } else
    if (val > INT_MAX) {
        val = INT_MAX;
        errno = ERANGE;
    }
    *dest = (int)val;
    return 1;
}

int validate_string(const char *buf, int *int1, int *int2) {
    char *p1, *p2;
    return parse_int(int1, buf, &p1)
    &&     *p1++ == ' '
    &&     parse_int(int2, p1, &p2)
    &&     *p2 == '\0');
}

以下只有一个scanf()

#include <stdio.h>

int validate_string(const char *buf, int *int1, int *int2) {
    int p1, p2, p3;
    char c;
    return sscanf(buf, " %n%d%1*[ ]%n %n%d%c", &p1, int1, &p2, &p3, int2, &c) == 2
        && p1 == 0 && p2 == p3;
}