wstringstream для LPWSTR - PullRequest
       24

wstringstream для LPWSTR

1 голос
/ 01 сентября 2011

Я создал строку, используя wstringstream, и мне нужно назначить ее члену struct типа LPWSTR.Я пытаюсь использовать my_stringstream.str().c_str(), но получаю следующую ошибку времени компиляции:

не может преобразовать из 'const wchar_t *' в 'LPWSTR'

Как я могу это сделать?Я пробовал много разных комбинаций приведений с большим количеством ошибок времени компиляции или случайным жаргоном, когда я пытался отобразить строку в графическом интерфейсе.

Ответы [ 6 ]

8 голосов
/ 01 сентября 2011

Ваша функция ожидает указатель на изменяемые данные, т.е. wchar_t*, но стандартный строковый класс предоставляет только указатель на константу.Предполагая, что ваша функция может действительно записывать в память, нам нужно предоставить ей действительный указатель.

Простой способ получить модифицируемый буфер - это, как всегда, vector:

std::vector<wchar_t> buf(mystring.begin(), mystring.end());
buf.push_back(0);                 // because your consumer expects null-termination

crazy_function(buf.data());
crazy_function(&buf[0]);          // old-style

// need a string again?
std::wstring newstr(buf.data());  // or &buf[0]
5 голосов
/ 01 сентября 2011

LPWSTR равно typedef d как wchar_t*. Вы пытаетесь конвертировать const wchar_t* в wchar_t*. Вы не можете сделать это безоговорочно.

Вы можете обойти это, используя const_cast, но только если вы уверены, что функция не изменит память:

wstring str = my_stringstream.str();
LPWSTR str = const_cast<LPWSTR>(str.c_str());

Обратите внимание, что вы не хотите делать const_cast<LPWSTR>(my_stringstream.str().c_str()) (если вы не передаете это функции), потому что это создаст временный строковый объект, получит его указатель, преобразует его в LPWSTR и тогда временная строка, которую вы получите от str(), будет уничтожена в конце этой строки, и ваш LPWSTR будет указывать на освобожденный блок памяти.

Если функция, которую вы передаете от LPWSTR до , изменяет строку, см. Ответ Керрека .

1 голос
/ 05 октября 2017
  wstringstream b;
    ..
    wchar_t z[100];
    b.read(z,100);

где длина строки меньше 101. это работает без unsetf(std::ios_base::skipws) и все это. И без ZeroMemory в массиве wchar_t.

0 голосов
/ 18 октября 2013
std::wstring temp(my_stringstream.str());
lpwstrVar = &temp[0];
0 голосов
/ 01 сентября 2011

Если вы абсолютно уверены, что содержимое строки не будет изменено, вы можете отбросить const с помощью static_cast; Ситуация, когда это может быть приемлемым, например, если вы используете некоторое struct для предоставления данных функции, но тот же struct также используется для его извлечения, так что членом является LPWSTR вместо LPCWSTR.

Если, напротив, функция, которой вы передадите struct, должна изменить строку, у вас есть две альтернативы.

Самый безопасный способ - выделить отдельную копию строки в виде необработанного динамического массива WCHAR и скопировать туда содержимое wstring. Возможно, вы захотите обернуть результат new умным указателем, если только вы не передаете владение строкой (и в этом случае вам, вероятно, придется использовать некоторую специальную функцию выделения).

Вы также можете передать указатель на внутренний буфер строки, используя &YourString[0], но (1) я не уверен, что он гарантированно работает по стандарту, и (2) он работает нормально, только если функция победила не меняйте длину вашей строки, добавляя L'\0' до ее конца; в этом случае вам также следует заново откорректировать фактическую длину строки.

Как в последнем, так и в первом случае вы должны быть уверены, что функция, которую вы передаете struct, не ожидает, что указанный буфер будет жить дольше, чем область действия вашего wstring (осторожно: * 1023) * это временный файл, который умирает на той самой строке, в которой вы его используете, вы должны назначить его новой переменной, чтобы расширить его область действия.

0 голосов
/ 01 сентября 2011

Причина этого довольно проста: LPWSTR расширяется до wchar_t *. Поскольку указатель на содержимое потока равен const, невозможно отбросить это const, если только не используется const_cast<LPWSTR>(my_stringstream.str().c_str()). Однако я бы посоветовал против этого (так как вы можете просто облажаться и / или изменить что-то другое таким образом. Делайте это только в том случае, если вы уверены, что оно не будет изменено или модификация не будет иметь значения.

Самое простое (и наиболее безопасное решение) - создать собственную копию строки, предоставленной wstringstream в буфере, и ссылаться на нее в структуре. Только не забудьте позже освободить память.

...