我有这个使用过的用例代码,在使用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::wcstok和breaking changes in VS 2015,其中提到C标准引入了第三个参数,
它使用内部的每线程上下文来跟踪调用状态, 正如strtok所做的那样。该功能现在具有签名
wchar_t* wcstok(wchar_t*, wchar_t const*, wchar_t**)
,并要求来电者 将上下文作为第三个参数传递给函数。
以愚蠢的声音为代价,我仍然会继续问,
任何人都可以用简单的术语解释第三个参数的用途,以及它如何从早期版本中更改std::wcstok
?
答案 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