What does _stscanf_s do?

What does _stscanf_s do?

本文关键字:do stscanf does What      更新时间:2023-10-16

我在一些代码中看到了这个函数,但在谷歌上找不到关于它的文档。有人能解释一下它的作用吗?有什么替代方案吗?

谢谢。

请参阅http://msdn.microsoft.com/en-us/library/tsbaswba%28VS.80%29.aspx:它是CCD_ 1的通用名称。

编辑:这里有方便的文档记录。_stscanf_s位于Windows平台上的TCHAR.H中。您可能可以使用sscanf_sswscanf_s

这篇MSDN文章展示了他们的"安全"sscanf替代品的_stscanf_s变体:

http://msdn.microsoft.com/en-us/library/t6z7bya3(v=vs.80).aspx

它是TCHAR变体,这意味着它应该能够支持ANSI字符和Unicode/Multi-byte,这取决于应用程序的编译方式。

您可以(在某种程度上)在更通用的C/C++实现中用sscanf替换它。

我假设最初的问题是关于safe和该函数的旧版本sscanf_s0之间的差异。我自己也在寻找同样的区别,归根结底是:_stscanf_s_stscanf在处理%s%c说明符的方式上不同。*_s函数将期望在下一个参数中传递其缓冲区的大小,如TCHAR s的数量。

最好的说明方式是使用以下代码示例:

    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弄错,或者如果您没有将它们与正确的参数匹配,则会引发内存/页面故障异常。