我在一些代码中看到了这个功能,我无法在google上找到关于它的文档。有人可以解释它的作用吗?有什么替代品吗?
感谢。
答案 0 :(得分:3)
请参阅http://msdn.microsoft.com/en-us/library/tsbaswba%28VS.80%29.aspx:它是sscanf_s
的通用名称。
编辑:方便记录here。 _stscanf_s
位于Windows平台上的TCHAR.H中。您可以使用sscanf_s
或swscanf_s
。
答案 1 :(得分:2)
我假设原始问题是关于safe
和此函数的旧unsafe
版本之间的差异。我自己也在寻找相同的差异,这就是它归结为:_stscanf_s
与_stscanf
和%s
说明符的处理方式不同%c
。 *_s
函数将期望缓冲区的大小在下一个参数中传递,作为TCHAR
的数量。
说明它的最好方法是使用这些代码示例:
const TCHAR* pSrcBuff = L"Date: 2015-12-25";
TCHAR buffDate[6] = {0};
TCHAR chDash1 = 0, chDash2 = 0;
int year = 0, month = 0, day = 0;
//Old "unsafe" method -- DON'T USE IT!
int count_found = _stscanf(pSrcBuff,
L"%s%d%c%d%c%d",
&buffDate,
&year,
&chDash1,
&month,
&chDash2,
&day
);
if(count_found == 6) //Number of specifiers read
{
//Success
ASSERT(lstrcmp(buffDate, L"Date:") == 0);
ASSERT(year == 2015);
ASSERT(chDash1 == L'-');
ASSERT(month == 12);
ASSERT(chDash2 == L'-');
ASSERT(day = 25);
}
请注意,如果我将buffDate[6]
更改为5或更低,则会导致堆栈损坏,可被“坏人”利用。
这就是为什么微软创建了一个新的“更安全”的方法,就是这样:
const TCHAR* pSrcBuff = L"Date: 2015-12-25";
TCHAR buffDate[6] = {0};
TCHAR chDash1 = 0, chDash2 = 0;
int year = 0, month = 0, day = 0;
//"Safe" version of the method
int count_found = _stscanf_s(pSrcBuff,
L"%s%d%c%d%c%d",
&buffDate, sizeof(buffDate) / sizeof(buffDate[0]),
&year,
&chDash1, sizeof(chDash1),
&month,
&chDash2, sizeof(chDash2),
&day
);
if(count_found == 6) //Number of specifiers read
{
//Success
ASSERT(lstrcmp(buffDate, L"Date:") == 0);
ASSERT(year == 2015);
ASSERT(chDash1 == L'-');
ASSERT(month == 12);
ASSERT(chDash2 == L'-');
ASSERT(day = 25);
}
在这种情况下,如果将buffDate[6]
设置为5或更低,_stscanf_s
函数将会失败,而不会覆盖buffDate
缓冲区的末尾。
请注意,scanf
组函数仍然存在危险(在我看来),如果您将%d
误认为是%s
,或者如果您不知道,则会抛出内存/页面错误异常t用正确的参数匹配它们。
答案 2 :(得分:1)
此MSDN文章显示了其“安全”_stscanf_s
替换的sscanf
变体:
http://msdn.microsoft.com/en-us/library/t6z7bya3(v=vs.80).aspx
它是TCHAR
变体,这意味着它应该能够支持ANSI字符和Unicode /多字节,具体取决于应用程序的编译方式。
您可以(稍微)在更通用的C / C ++实现上用sscanf
替换它。