特定的 sscanf 用法
Particular sscanf usage
我正在使用 sscanf read/parse 将 3 个字符的字符串转换为 int,如下所示:
char strId[4] = "123";
int i;
int count = sscanf(strId, "%i" &i);
我正在测试 count==1
以检查解析是成功还是失败。
"123"
正确成功 - 我想将其视为一个数字。
"aaa"
正确失败 - 我不想将其视为数字。
但是
"2aa"
成功 (count==1, i==2)- 但我想将此标识为失败,因为我不想将其视为一个数字。
如何简单解析strId满足以上条件?
char str[255];
int count = sscanf((const char*)strId, "%i%254s", &i, str);
如果返回 count == 1
可以吗?
使用strtol(3)
。它允许指定 "end-of-parsing" 指针(下面的 endptr
)。转换完成后,您可以检查它是否指向字符串的末尾。如果不是,则输入中有非数字字符。
long strtol(const char *restrict str, char **restrict endptr, int base);
来自man strtol
:
If endptr is not NULL, strtol() stores the address of the first
invalid character in *endptr. If there were no digits at all,
however, strtol() stores the original value of str in *endptr. (Thus,
if *str is not '[=14=]' but **endptr is '[=14=]' on return, the entire string
was valid.)
有了strtol
,这很容易做到这一点
#include <stdio.h>
#include <stdlib.h>
char string[] = "123xyz";
char *endptr;
int value;
value = strtol(string, &endptr, 10);
if ((*string != '[=10=]') && (*endptr == '[=10=]'))
printf("%s is a number and has no unconvertible characters", string);
/* and now 'value' contains the integer value. */
如果你想使用 sscanf()
那么这也应该这样做
#include <stdio.h>
#include <string.h>
char string[] = "123";
int count;
int value;
int length;
length = strlen(string);
if ((sscanf(string, "%d%n", &value, &count) == 1) && (count == length))
printf("%s is a number and has no unconvertible characters", string);
/* and now 'value' contains the integer value. */
一个sscanf()
方法,使用"%n"
.
"%n"
保存扫描停止的位置。
char strId[4] = "123";
int n = 0
sscanf(strId, "%i %n" &i, &n);
if (n == 0 || strId[n] != '[=10=]') Handle_ProblemInput(strId);
这将通过:"123"
、" 123"
、"123 "
。
失败:"123a"
、""
、" abc"
.
May/may 未检测到 int
溢出 "12345678901234567890"
。
[编辑]
"%n"
的优点在于它可以用于复杂的格式以及以固定文本结尾的格式。 IOWs,只需检测扫描是否一直到 '[=24=]'
?
int n = 0;
sscanf(buf, " %i %f %7s ,,, %c blah foo %n", ...);
if (n == 0 || buf[n] != '[=11=]') Handle_ProblemInput(buf);
我正在使用 sscanf read/parse 将 3 个字符的字符串转换为 int,如下所示:
char strId[4] = "123";
int i;
int count = sscanf(strId, "%i" &i);
我正在测试 count==1
以检查解析是成功还是失败。
"123"
正确成功 - 我想将其视为一个数字。
"aaa"
正确失败 - 我不想将其视为数字。
但是
"2aa"
成功 (count==1, i==2)- 但我想将此标识为失败,因为我不想将其视为一个数字。
如何简单解析strId满足以上条件?
char str[255];
int count = sscanf((const char*)strId, "%i%254s", &i, str);
如果返回 count == 1
可以吗?
使用strtol(3)
。它允许指定 "end-of-parsing" 指针(下面的 endptr
)。转换完成后,您可以检查它是否指向字符串的末尾。如果不是,则输入中有非数字字符。
long strtol(const char *restrict str, char **restrict endptr, int base);
来自man strtol
:
If endptr is not NULL, strtol() stores the address of the first invalid character in *endptr. If there were no digits at all, however, strtol() stores the original value of str in *endptr. (Thus, if *str is not '[=14=]' but **endptr is '[=14=]' on return, the entire string was valid.)
有了strtol
,这很容易做到这一点
#include <stdio.h>
#include <stdlib.h>
char string[] = "123xyz";
char *endptr;
int value;
value = strtol(string, &endptr, 10);
if ((*string != '[=10=]') && (*endptr == '[=10=]'))
printf("%s is a number and has no unconvertible characters", string);
/* and now 'value' contains the integer value. */
如果你想使用 sscanf()
那么这也应该这样做
#include <stdio.h>
#include <string.h>
char string[] = "123";
int count;
int value;
int length;
length = strlen(string);
if ((sscanf(string, "%d%n", &value, &count) == 1) && (count == length))
printf("%s is a number and has no unconvertible characters", string);
/* and now 'value' contains the integer value. */
一个sscanf()
方法,使用"%n"
.
"%n"
保存扫描停止的位置。
char strId[4] = "123";
int n = 0
sscanf(strId, "%i %n" &i, &n);
if (n == 0 || strId[n] != '[=10=]') Handle_ProblemInput(strId);
这将通过:"123"
、" 123"
、"123 "
。
失败:"123a"
、""
、" abc"
.
May/may 未检测到 int
溢出 "12345678901234567890"
。
[编辑]
"%n"
的优点在于它可以用于复杂的格式以及以固定文本结尾的格式。 IOWs,只需检测扫描是否一直到 '[=24=]'
?
int n = 0;
sscanf(buf, " %i %f %7s ,,, %c blah foo %n", ...);
if (n == 0 || buf[n] != '[=11=]') Handle_ProblemInput(buf);