特定的 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);