_stscanf_s做什么?

时间:2011-06-27 07:28:04

标签: c++ c mfc

我在一些代码中看到了这个功能,我无法在google上找到关于它的文档。有人可以解释它的作用吗?有什么替代品吗?

感谢。

3 个答案:

答案 0 :(得分:3)

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

编辑:方便记录here_stscanf_s位于Windows平台上的TCHAR.H中。您可以使用sscanf_sswscanf_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替换它。