当输入字符串是例如“4.5”时,我希望sscanf不要将其解析为整数。但现在它这样做了。我的代码看起来像这样:if (sscanf(str, "%d", &val) == 0) { return NULL; }这当然不起作用,因为sscanf将“4.5”解析为4,并且不返回NULL多谢帮忙
if (sscanf(str, "%d", &val) == 0) { return NULL; }
nxagd54h1#
sscanf("4.5", "%d", &val)不会将“4.5”解析为4。它将“4”解析为4,而不解析“.5”。您可以验证sscanf不会解析字符串中的任何其他字符:
sscanf("4.5", "%d", &val)
sscanf
int val; char c; if (sscanf(str, "%d%c", &val, &c) != 1) { return NULL; }
6rqinv9w2#
sscanf()将跳过白色。它将解析前缀(在本例中为4)并忽略后缀(在本例中为.5)。如果转换的结果无法在对象中表示,则该行为未定义。1.我建议写一个函数来解析一个整数;您可以使用strtol()进行额外的边界检查:
sscanf()
4
.5
strtol()
#include <ctype.h> #include <stdio.h> #include <string.h> #include <limits.h> #define FS " " const char *parse_int(const char *s, int *v) { if(!s) return NULL; int sign = 1; if(*s == '-') { sign = -1; s++; } if(!isdigit(*s)) return NULL; *v = 0; for(; isdigit(*s); s++) { int d = sign * (*s - '0'); if(*v < (INT_MIN + d) / 10 || *v > (INT_MAX + d) / 10) return NULL; *v = *v * 10 + d; } return s; } const char *parse_str(const char *s, const char *expect) { if(!s || strncmp(s, expect, strlen(expect))) return NULL; return s + strlen(expect); } int main() { const char *str = "4.5 "; int d; // note: str will be set to NULL on parse failure; use different `const char *` variables to keep track of progress. (str = parse_int(str, &d)) && (str = parse_str(str, FS)); if(!str) { printf("parse failed"); return 1; } }
如果这对你不起作用,我有两个建议:1.使用%n来计算字符串的剩余部分,丢弃它,因为它不是字段分隔符:
%n
#include <stdio.h> #include <string.h> #define FS " " int main() { char *str = "4.5"; int val; int pos; int rv = sscanf(str, "%d%n", &val, &pos); if(rv != 1 || strncmp(str + pos, FS, sizeof FS - 1)) { printf("parse failed\n"); return 1; } }
1.读取double而不是int,并检查它是否是整数且在正确的范围内:
double
int
#include <limits.h> #include <stdio.h> #include <string.h> #define delta 1e-6 int main() { char *str = "4.5"; double d; int rv = sscanf(str, "%lf", &d); if(d - (int) d > delta || d > INT_MAX || d < INT_MIN) { printf("parse failed\n"); return 1; } }
2条答案
按热度按时间nxagd54h1#
sscanf("4.5", "%d", &val)
不会将“4.5”解析为4。它将“4”解析为4,而不解析“.5”。您可以验证sscanf
不会解析字符串中的任何其他字符:6rqinv9w2#
sscanf()
将跳过白色。它将解析前缀(在本例中为4
)并忽略后缀(在本例中为.5
)。如果转换的结果无法在对象中表示,则该行为未定义。1.我建议写一个函数来解析一个整数;您可以使用
strtol()
进行额外的边界检查:如果这对你不起作用,我有两个建议:
1.使用
%n
来计算字符串的剩余部分,丢弃它,因为它不是字段分隔符:1.读取
double
而不是int
,并检查它是否是整数且在正确的范围内: