2016-07-01 57 views
6

我有这样的代码,当使用VS 2015 C++编译器进行编译时会产生警告。在VS 2015中的std :: wcstok

#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

+2

在猜测,这是一样的strtod的最后一个参数。它包含下一个要解析的项目,因此可以在下一次调用时将其馈送到第一个参数中,这将使其线程安全。 – cup

+1

全球CRT状态是一个非常讨厌的错误的食谱。 strtok()肯定是一个更邪恶的,errno,strerror(),asctime(),gmtime(),setlocale(),tmpfile(),tmpnam(),fcvt(),ecvt()值得荣誉提及。 –

回答

0

旧版本与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