Что делает _stscanf_s? - PullRequest
       2

Что делает _stscanf_s?

3 голосов
/ 27 июня 2011

Я видел эту функцию в некотором коде, и я не могу найти документацию в Google об этом.Может кто-нибудь объяснить, что он делает, и есть ли альтернативы этому?

Спасибо.

Ответы [ 3 ]

3 голосов
/ 27 июня 2011

См. http://msdn.microsoft.com/en-us/library/tsbaswba%28VS.80%29.aspx: это общее имя для sscanf_s.

РЕДАКТИРОВАТЬ: что удобно документировано здесь . _stscanf_s находится в TCHAR.H на платформах Windows. Вероятно, вы можете обойтись без использования sscanf_s или swscanf_s.

2 голосов
/ 27 декабря 2015

Я предполагаю, что первоначальный вопрос был о разнице между safe и более старой unsafe версией этой функции. Я сам искал ту же разницу, и вот к чему она сводится: _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 или ниже, это приведет к повреждению стека, которое может быть использовано "плохими парнями".

Вот почему Microsoft создала новый «более безопасный» метод, который выглядит так:

    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 или если вы не сопоставите их с правильными параметрами .

1 голос
/ 27 июня 2011

В этой статье MSDN показан вариант _stscanf_s их «безопасных» замен sscanf:

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

Это вариант TCHAR, что означает, что он долженбыть в состоянии поддерживать символы ANSI и Unicode / Multi-byte, в зависимости от того, как приложение скомпилировано.

Вы можете (несколько) заменить его на sscanf в более общей реализации C / C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...