VS 2015中的std :: wcstok

时间:2016-07-01 11:42:50

标签: c c++11 visual-studio-2015 c11

我有这个使用过的用例代码,在使用VS 2015 C ++编译器编译时产生警告。

#include <cwchar>
#include <iostream>

int main()
{
    wchar_t input[100] = L"A bird came down the walk";
    wchar_t* token = std::wcstok(input, L" ");
    while (token) {
        std::wcout << token << '\n';
        token = std::wcstok(nullptr, L" ");
    }
}

这产生了以下警告。

warning C4996: 'wcstok': wcstok has been changed to conform with the ISO C standard, adding an extra context parameter. To use the legacy Microsoft wcstok, define _CRT_NON_CONFORMING_WCSTOK.
1>  c:\program files (x86)\windows kits\10\include\10.0.10240.0\ucrt\corecrt_wstring.h(254): note: see declaration of 'wcstok'

warning C4996: 'wcstok': wcstok has been changed to conform with the ISO C standard, adding an extra context parameter. To use the legacy Microsoft wcstok, define _CRT_NON_CONFORMING_WCSTOK.
1>  c:\program files (x86)\windows kits\10\include\10.0.10240.0\ucrt\corecrt_wstring.h(254): note: see declaration of 'wcstok'

在线查询,我读到了std::wcstokbreaking changes in VS 2015,其中提到C标准引入了第三个参数,

  

它使用内部的每线程上下文来跟踪调用状态,   正如strtok所做的那样。该功能现在具有签名   wchar_t* wcstok(wchar_t*, wchar_t const*, wchar_t**),并要求来电者   将上下文作为第三个参数传递给函数。

以愚蠢的声音为代价,我仍然会继续问, 任何人都可以用简单的术语解释第三个参数的用途,以及它如何从早期版本中更改std::wcstok

1 个答案:

答案 0 :(得分:1)

旧版本与strtok类似,并使用全局线程本地存储来存储超过最后一个令牌末尾的位置。

使用方法的问题是它不允许嵌套函数,如strtok / wcstok

想象一下,我们有一个像"r0c0;r0c1\nr1c0;r1c1"这样的字符串(一个包含2行和2列的表),我们想先将它拆分成行,然后将每行拆分成列。

要做到这一点,我们需要2个循环。使用旧方法这是不可能的,因为嵌套循环将覆盖外循环的状态。使用新方法,每个循环可以将单独的状态存储在单独的变量中:

#include <cwchar>
#include <iostream>

int main()
{
    wchar_t input[] = L"r0c0;r0c1\n"
                      L"r1c0;r1c1";
    wchar_t *rowstate;
    wchar_t *row = std::wcstok(input, L"\n", &rowstate);

    while (row != nullptr) {
        std::wcout << L"Row: " << row << std::endl;

        wchar_t *colstate;
        wchar_t *col = std::wcstok(row, L";", &colstate);

        while (col != nullptr) {
            std::wcout << "  Col: " << col << std::endl;
            col = std::wcstok(nullptr, L" ", &colstate);
        }

        row = std::wcstok(nullptr, L" ", &rowstate);
    }
}

输出是:

Row: r0c0;r0c1
  Col: r0c0
  Col: r0c1
Row: r1c0;r1c1
  Col: r1c0
  Col: r1c1