【C++】sscanf 的返回值

1,376 阅读2分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

sscanf读取格式化的字符串中的数据。

swscanf 是 sscanf 的宽字符版本;swscanf 的参数是宽字符串。 swscanf不处理 Unicode 全角十六进制或"兼容性区"字符。 除此以外,swscanf 和 sscanf 的行为完全相同。

sscanf 与 scanf 类似,都是用于输入的,只是后者以键盘( stdin )为输入源,前者以固定字符串为输入源。

sscanf() 的返回值,函数将返回成功赋值的字段个数;返回值不包括已读取但未赋值的字段个数。 返回值为 0 表示没有将任何字段赋值。 如果在第一次读取之前到达字符串结尾,则返回EOF。

如果buffer或format是NULL调用指针,无效参数处理程序,如中所述参数验证。 如果允许继续执行,则这些函数返回 -1 并将errno设置为EINVAL。

成功则返回参数数目,失败则返回-1,错误原因存于 errno 中。举例来说

int cnt;
char str[256] = "";
if (!sscanf(str, "cnt = %d", &cnt))
	return;
if (cnt == 0)
	return;
float * point = new float[cnt];

结果,崩溃,backtrace 显示崩溃在 new 操作上。如果打 log,可知,cnt 可能为负值。因此,int cnt = 0; 声明即赋值是个好主意。 但是,因为 sscanf 在当 str 是空字符串时,返回值为 -1,而 所有非 0 int 均为 true,因此 -1 取非值为 false,所以中间那个 if 语句也没能拦住这次崩溃。 因此,这段代码最好这么写

int cnt = 0;
char str[256] = "";
if (sscanf(str, "cnt = %d", &cnt) <= 0)
	return;
if (cnt == 0)
	return;
float * point new float[cnt];

在这种情况下, 当 str = "cnt = 3" 时, sscanf 的返回值为 1, 当 str = "something else" 时,sscanf 的返回值为0, 当 str = "cnt = 3 cnt = 3 cnt = 4" 时, sscanf 的返回值为 3?那么 cnt 的值为啥? 经验证,当 str = "cnt = 3 cnt = 3" 时,sscanf 的返回值仍为 1 。

当代码写成如下:

int cnt, mnt;
char str[256] = "cnt = 56,78vertex = 333";
char str2[256];
sscanf(str, "cnt = %d,%d,%s", &cnt, &mnt, str2);

那么,sscanf 的返回值将等于 3。str2 为 "vertex" 当然,以上代码中仍有问题, cnt mnt 需初始化,,str2 也应该用 memset 赋 0。