This statement:
line = wcstok(readMap,L";");
Reads the first delimited line in the buffer. OK.
However, in your loop, this statement:
line = wcstok(NULL,L";");
Is at the top of the loop and is thus throwing away that first line on the 1st iteration and then reading the next delimited line. Eventually, your loop will reach the end of the buffer and wcstok() will return NULL, but you are not checking for that condition before using line:
line = wcstok(readMap,L";"); // <-- reads the first line
while (line != NULL) {
line = wcstok(NULL,L";"); // <-- 1st iteration throws away the first line
wstring wstr(line); // <-- line will be NULL on last iteration
//...
}
The line = wcstok(NULL,L";"); statement needs to be moved to the bottom of the loop instead:
wchar_t* line = wcstok(readMap, L";");
while (line != NULL)
{
// use line as needed...
line = wcstok(NULL, L";");
}
I would suggest changing the while loop into a for loop to enforce that:
for (wchar_t* line = wcstok(readMap, L";"); (line != NULL); line = wcstok(NULL, L";"))
{
// use line as needed...
}
On the other hand, since you are using C++, you should consider using std:wistringstream and std:getline() instead of wcstok():
#include <string>
#include <sstream>
// after LoadString() exits, resid contains the
// number of character copied into readMap...
std::wistringstream iss(std::wstring(readMap, resid));
std::wstring line;
while (std::getline(iss, line, L';'))
{
// use line as needed...
}
But either way, this statement is just plain wrong:
string str(wstr.begin(), wstr.end()); // Problem
This statement will work correctly only if the std::wstring contains ASCII characters in the #0 - #127 range. For non-ASCII characters, you have to perform a data conversion instead to avoid data loss for Unicode characters > U+00FF.
Since you are running on Windows, you can use the Win32 API WideCharToMultiByte() function:
std::wstring line;
while (std::getline(iss, line, L';'))
{
std::string str;
// optionally substitute CP_UTF8 with any ANSI codepage you want...
int len = WideCharToMultiByte(CP_UTF8, 0, line.c_str(), line.length(), NULL, 0, NULL, NULL);
if (len > 0)
{
str.resize(len);
WideCharToMultiByte(CP_UTF8, 0, line.c_str(), line.length(), &str[0], len, NULL, NULL);
}
// use str as needed...
MessageBoxW(0, line.c_str(), L"line", 0);
MessageBoxA(0, str.c_str(), "str", 0);
}
Or, if you are using C++11 or later, you can use the std::wstring_convert class (only for UTF-8/16/32 conversions, though):
#include <locale>
std::wstring line;
while (std::getline(iss, line, L';'))
{
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> conv;
std::string str = conv.to_bytes(line);
// use str as needed...
MessageBoxW(0, line.c_str(), L"line", 0);
MessageBoxA(0, str.c_str(), "str", 0);
}