-1

I need to split LPWSTR with multiple delimiters & return array of LPWSTR in c++. How to do it? I tried to do from the following question: How to split char pointer with multiple delimiters & return array of char pointers in c++?

But it prints ?? for each wstring. What's wrong with it?

can I do it as I tried follow? If so what's the mistake I made? If not how to do it?

std::vector<wstring> splitManyW(const wstring &original, const wstring &delimiters)
{
    std::wstringstream stream(original);
    std::wstring line;
    vector <wstring> wordVector;

    while (std::getline(stream, line)) 
    {
        std::size_t prev = 0, pos;
        while ((pos = line.find_first_of(delimiters, prev)) != std::wstring::npos)
        {
            if (pos > prev)
            {
                wstring toPush = line.substr(prev, pos-prev);
                //wstring toPushW = toWide(toPush);
                wordVector.push_back(toPush);
            }
            prev = pos + 1;
        }
        if (prev < line.length())
        {
            wstring toPush = line.substr(prev, std::wstring::npos);
            //wstring toPushW = toWide(toPush);
            wordVector.push_back(toPush);
        }
    }
    for (int i = 0; i< wordVector.size(); i++)
    {
        //cout << wordVector[i] << endl;
        wprintf(L"Event message string: %s\n", wordVector[i]);
    }
    return wordVector;
}

int main()
{
    wstring original = L"This:is\nmy:tst?why I hate";
    wstring separators = L":? \n";

    vector<wstring> results = splitManyW(original, separators);

    getchar();
}
Community
  • 1
  • 1
Janu
  • 59
  • 6
  • 1
    Fyi, `wordVector[i]` ===> `wordVector[i].c_str()` in your `wprintf` invoke. – WhozCraig Aug 08 '15 at 17:07
  • std::vector is not the same as an array of LPWSTR. – john Aug 08 '15 at 17:21
  • Clang actually tells you about this: *error: cannot pass object of non-trivial type 'value_type' (aka 'std::__cxx11::basic_string') through variadic function; call will abort at runtime [-Wnon-pod-varargs]* – chris Aug 08 '15 at 17:26
  • Before moving on, have a look at [The Definitive C++ Book Guide and List](http://stackoverflow.com/q/388242/1889329). – IInspectable Aug 08 '15 at 18:17

3 Answers3

1

You're not properly accessing the wchar_t* exposed from std::wstring when you print your final tokens. Further, your output format specifier is incorrect. Per the wprintf documentation (see here), in particular "If the l specifier is used, the argument must be a pointer to the initial element of an array of wchar_t.".

A few modifications and stripping out some redundancies gives the following:

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using std::wstring;
using std::vector;

std::vector<wstring> splitManyW(const wstring &original, const wstring &delimiters)
{
    std::wstringstream stream(original);
    std::wstring line;
    vector <wstring> wordVector;

    while (std::getline(stream, line))
    {
        std::size_t prev = 0, pos;
        while ((pos = line.find_first_of(delimiters, prev)) != std::wstring::npos)
        {
            if (pos > prev)
                wordVector.emplace_back(line.substr(prev, pos-prev));

            prev = pos + 1;
        }

        if (prev < line.length())
            wordVector.emplace_back(line.substr(prev, std::wstring::npos));
    }

    return wordVector;
}

int main()
{
    wstring original = L"This:is\nmy:tst?why I hate";
    wstring separators = L":? \n";

    vector<wstring> results = splitManyW(original, separators);

    for (auto const& w : results)
        wprintf(L"Event message string: %ls\n", w.c_str());

    getchar();
}

Output

Event message string: This
Event message string: is
Event message string: my
Event message string: tst
Event message string: why
Event message string: I
Event message string: hate

Note: I would have preferred using formatted stream output using operator <<, but that is somewhat unrelated to your question.

Best of luck.

WhozCraig
  • 65,258
  • 11
  • 75
  • 141
0

You should have executed it under a debugger. You would have seen immediately that your parsing is correct, so is your vector.

The problem is that you are trying to use to old C wprintf with format %s which expects a C string (a null terminated char array), and you pass a std::string which is a totally different object.

You can either :

  • do it the C way, getting the C string contained by the std::string:

    wprintf(L"Event message string: %s\n", wordVector[i].c_str());
    
  • do it the C++ way, using wcout:

    wcout << L"Event message string: " << wordVector[i] << std::endl;
    

But your return value is not an array of LPWSTR but a vector of std::string.

You should first allocate the array of pointers to char array, then individually allocate the char arrays, return that... and do not forget to free everything.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
-1

LPWSTR is wchar_t*, so basically what you need is wcstok.

Alan Tsui
  • 31
  • 2