Std :: wcstok in VS 2015

I have this tinted used code, which when compiling with the VS 2015 C ++ compiler, gives a warning.

#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" "); } } 

This triggered the following warnings.

 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' 

Going up on the Internet, I read about std :: wcstok and break changes in VS 2015 , which mentions that the C standard introduced a third parameter and that

He used the internal context for threads to track state between calls, as is done for strtok. Now the function has the signature wchar_t* wcstok(wchar_t*, wchar_t const*, wchar_t**) and requires a call to pass the context as the third argument to the function.

Due to the fact that the sound sounds stupid in its essence, I will go ahead and ask anyway. Can anyone explain the purpose of this third parameter in simple words and how did it change std::wcstok from its earlier version?

+6
source share
1 answer

The old version was similar to strtok and used local storage of global flows to store the position at the end of the last token.

The problem with the approach used is that it does not allow nesting functions such as strtok / wcstok .

Imagine we have a row like "r0c0;r0c1\nr1c0;r1c1" (a table with two rows and two columns), and we want to split it into rows first and then divide each row into columns.

For this we need 2 cycles. Using the old approach, this is not possible, since the nested loop will overwrite the state of the outer loop. With the new approach, each cycle can have a separate state stored in separate variables:

 #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); } } 

Exit:

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

All Articles