与sscanf_s混淆

时间:2014-06-06 09:41:01

标签: c

我遇到了sscanf_s的问题,基本上我有这行代码:

sscanf_s( line.c_str(),
          "<float_array id=\"%*s[^\"]\" count=\"%*d\">%[^<]s",
          numString);

我正在给它提供这一行文字:

<float_array id="Cube-mesh-positions-array" count="24">1 1 -1 1 -1 -1 -1 -0.9999998 -1    -0.9999997 1 -1 1 0.9999995 1 0.9999994 -1.000001 1 -1 -0.9999997 1 -1 1 1</float_array>

我想要实现的是读取count="24">之后编写的数字数组并将其传递给另一个函数,但是numString在通过等式后保留值""因此导致后续功能失败。如果有人能让我深入了解为什么会这样,我会非常感激。

我测试的一个简短的SSCCE显示问题出在其他地方,我将不得不进一步调查 - 抱歉浪费你的时间,并感谢你花时间去尝试帮助我。

2 个答案:

答案 0 :(得分:6)

函数sscanf_s是Microsoft的发明,旨在比标准sscanf函数“更安全”。

因此,如果您使用的是"%s""%c",则需要两个参数:一个是写入输入的缓冲区,一个整数指定缓冲区的可用大小,以便长输入字符串不会导致缓冲区溢出。

不幸的是,这对函数的用户来说并不那么明显(比如你自己),导致频繁使用该函数(这有点降低了暗示的“安全性”)。

Link to the Microsoft docs;请参阅“备注”部分。

所以你所拥有的是未定义的行为,因为sscanf_s尝试从堆栈中读取一个尚未放置的整数。你最终很幸运,内存读取显然是零,所以零字节写入numString

这应该做得很好:

size_t BUFSIZE = 50;
char numString[ BUFSIZE ];
sscanf_s( line.c_str(),
          "<float_array id=\"%*s[^\"]\" count=\"%*d\">%[^<]s",
          numString, BUFSIZE );

请注意numString实际上 char[]。您的问题最初标记为C ++;如果numString实际上是std::string,请注意您不能将scanf系列函数与std::string参数一起使用。


(对不起编辑,前几次弄错了。那格式字符串是...... ;-))

答案 1 :(得分:1)

char numString[ 256 ];
sscanf_s( line.c_str(),
          "<float_array id=\"%*[^\"]\" count=\"%*d\">%255[^<]",
          numString, 256);