2016-07-01 38 views
6

VS 2015 C++コンパイラでコンパイルすると警告が表示されます。std :: wcstok in VS 2015

#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とCの標準は、第三パラメータとその

それは呼び出しにわたって状態を追跡するために内部、スレッドごとのコンテキストを使用を導入したことに言及breaking changes in VS 2015、 strtokの場合は と同じです。関数は今では署名が wchar_t* wcstok(wchar_t*, wchar_t const*, wchar_t**)であり、呼び出し元には が3番目の引数としてコンテキストを渡す必要があります。本質的に愚かな響きのコストで

、私はまだ先に行くと聞いて、 ます誰でも簡単な言葉で、この三番目のパラメータの目的を説明していただけますとどのようにそれはその以前のバージョンから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