sscanf和尾随字符

时间:2014-02-19 17:36:23

标签: c scanf

我正在尝试使用sscanf进行简单的测试和转换,但是我遇到了一个问题,忽略了字符串中的尾随垃圾。我的示例代码是:

char *arg = "some user input argument";
int val = 0;
if (sscanf(arg, "simple:%d", &val) == 1) {
    opt = SIMPLE;
} else if (strcmp(arg, "none") == 0) {
    opt = NONE;
} else {
    // ERROR!!!
}

这适用于预期的输入,例如:

arg = "simple:2"  --> opt = SIMPLE  val = 2
arg = "none"      --> opt = NONE    val = 0

但我的问题是在“简单”值被忽略后尾随字符

ACTUAL : arg = "simple:2GARBAGE" --> opt = SIMPLE  val = 2
DESIRED: arg = "simple:2GARBAGE" --> ERROR!!!

让sscanf报告尾随垃圾的简单方法是什么?或者,既然我读过“scanf是邪恶的”,是否有一个简单的(最好是1-liner)替代sscanf来解决上述问题?

2 个答案:

答案 0 :(得分:6)

sscanf()额外char。找不到它。

char ch;
// If _nothing_ should follow the `int`
if (sscanf(arg, "simple:%d%c", &val, &ch) == 1) Success();
// or if trailing white-space is OK
if (sscanf(arg, "simple:%d %c", &val, &ch) == 1) Success();

另一个惯用解决方案使用%n

int n;
// If _nothing_ should follow the `int`
if (sscanf(arg, "simple:%d%n", &val, &n) == 1 && arg[n] == '\0') Success();
// or if trailing white-space is OK
if (sscanf(arg, "simple:%d %n", &val, &n) == 1 && arg[n] == '\0') Success();

答案 1 :(得分:4)

您可以使用以下内容:

char rest[64] = "";
[...]
if ( sscanf(arg, "simple:%d%s", &val, rest) == 1 ) {

并测试rest的内容或长度。

这是有效的,因为%s后面的%d会吃掉有效数字后面的任何字符。您可以根据需要调整rest的大小。

有关工作示例,请参阅here