我正在尝试使用带有完全符合以下格式的字符串的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 }
答案 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;
}