What does _stscanf_s do?
I saw this function in some code开发者_开发百科 and I can't find documentation on google about it. Can someone explain what it does and are there any alternatives to this ?
Thanks.
See http://msdn.microsoft.com/en-us/library/tsbaswba%28VS.80%29.aspx: it is a generic name for sscanf_s
.
EDIT: which is conveniently documented here. _stscanf_s
is in TCHAR.H on Windows platforms. You can probably get away with using sscanf_s
or swscanf_s
.
This MSDN article shows the _stscanf_s
variant of their "secure" sscanf
replacements:
http://msdn.microsoft.com/en-us/library/t6z7bya3(v=vs.80).aspx
It is a TCHAR
variant, which means that it should be able to support ANSI characters, and Unicode/Multi-byte, depending on how the app is compiled.
You could (somewhat) replace it with sscanf
on a more generic C/C++ implementation.
I'm assuming that the original question was about the difference between the safe
and an older unsafe
version of this function. I was looking for the same difference myself, and here's what it boils down to: _stscanf_s
is different from _stscanf
in the way it treats %s
and %c
specifiers. The *_s
function will expect the sizes of their buffers to be passed in the next parameter, as the number of TCHAR
s.
The best way to illustrate it is with these code samples:
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);
}
Note that if I change buffDate[6]
to 5 or lower, it will result in a stack corruption, which can be exploited by "bad guys."
That is why Microsoft created a new "safer" method, that goes as such:
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);
}
In this case, if you set buffDate[6]
to 5 or lower, the _stscanf_s
function will simply fail, without overwriting the end of the buffDate
buffer.
Note that scanf
group of functions is still dangerous (in my view) and will throw memory/page-fault exceptions if you mistake %d
with %s
, or if you don't match them with correct parameters.
精彩评论