Respostas:
str.c_str()
fornece um const char *
, que é um LPCSTR
(Ponteiro longo para STRing constante) - significa que é um ponteiro para uma 0
string terminada de caracteres. W
significa string larga (composta de em wchar_t
vez de char
).
Ligue c_str()
para obter um const char *
( LPCSTR
) de a std::string
.
Está tudo no nome:
LPSTR
- ponteiro (longo) para string - char *
LPCSTR
- ponteiro (longo) para string constante - const char *
LPWSTR
- ponteiro (longo) para string Unicode (larga) - wchar_t *
LPCWSTR
- ponteiro (longo) para string Unicode (ampla) constante - const wchar_t *
LPTSTR
- ponteiro (longo) para TCHAR (Unicode se UNICODE for definido, ANSI se não) string - TCHAR *
LPCTSTR
- ponteiro (longo) para string TCHAR constante - const TCHAR *
Você pode ignorar a parte L (longa) dos nomes - é um resquício do Windows de 16 bits.
Estes são typedefs definidos pela Microsoft que correspondem a:
LPCSTR: ponteiro para string const terminada em nulo de char
LPSTR: ponteiro para string de caracteres terminada em nulo de char
(geralmente um buffer é passado e usado como um parâmetro de 'saída')
LPCWSTR: ponteiro para string terminada em nulo de const wchar_t
LPWSTR: ponteiro para string terminada em nulo de wchar_t
(geralmente um buffer é passado e usado como um parâmetro de 'saída')
Para "converter" a std::string
em um LPCSTR depende do contexto exato, mas normalmente a chamada .c_str()
é suficiente.
Isso funciona.
void TakesString(LPCSTR param);
void f(const std::string& param)
{
TakesString(param.c_str());
}
Observe que você não deve tentar fazer algo assim.
LPCSTR GetString()
{
std::string tmp("temporary");
return tmp.c_str();
}
O buffer retornado por .c_str()
pertence à std::string
instância e só será válido até a próxima modificação ou destruição da string.
Converter a std::string
em a LPWSTR
é mais complicado. Querer um LPWSTR
implica que você precisa de um buffer modificável e também precisa ter certeza de que entende qual codificação de caracteres o std::string
está usando. Se o std::string
contém uma string usando a codificação padrão do sistema (assumindo janelas, aqui), então você pode encontrar o comprimento do amplo buffer de caracteres necessário e realizar a transcodificação usandoMultiByteToWideChar
(uma função API do Win32).
por exemplo
void f(const std:string& instr)
{
// Assumes std::string is encoded in the current Windows ANSI codepage
int bufferlen = ::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), NULL, 0);
if (bufferlen == 0)
{
// Something went wrong. Perhaps, check GetLastError() and log.
return;
}
// Allocate new LPWSTR - must deallocate it later
LPWSTR widestr = new WCHAR[bufferlen + 1];
::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), widestr, bufferlen);
// Ensure wide string is null terminated
widestr[bufferlen] = 0;
// Do something with widestr
delete[] widestr;
}
Usando LPWSTR
você pode alterar o conteúdo da string para onde ela aponta. Usando LPCWSTR
você não pode alterar o conteúdo da string para onde ela aponta.
std::string s = SOME_STRING;
// get temporary LPSTR (not really safe)
LPSTR pst = &s[0];
// get temporary LPCSTR (pretty safe)
LPCSTR pcstr = s.c_str();
// convert to std::wstring
std::wstring ws;
ws.assign( s.begin(), s.end() );
// get temporary LPWSTR (not really safe)
LPWSTR pwst = &ws[0];
// get temporary LPCWSTR (pretty safe)
LPCWSTR pcwstr = ws.c_str();
LPWSTR
é apenas um ponteiro para a string original. Você não deve retorná-lo da função usando o exemplo acima. Para não ser temporário, LPWSTR
você deve fazer uma cópia da string original na pilha. Confira o exemplo abaixo:
LPWSTR ConvertToLPWSTR( const std::string& s )
{
LPWSTR ws = new wchar_t[s.size()+1]; // +1 for zero at the end
copy( s.begin(), s.end(), ws );
ws[s.size()] = 0; // zero at the end
return ws;
}
void f()
{
std::string s = SOME_STRING;
LPWSTR ws = ConvertToLPWSTR( s );
// some actions
delete[] ws; // caller responsible for deletion
}
A MultiByteToWideChar
resposta que Charles Bailey deu é a correta. Como LPCWSTR
é apenas um typedef para const WCHAR*
, widestr
no código de exemplo ele pode ser usado sempre que um LPWSTR
for esperado ou onde um LPCWSTR
for esperado.
Um pequeno ajuste seria usar em std::vector<WCHAR>
vez de uma matriz gerenciada manualmente:
// using vector, buffer is deallocated when function ends
std::vector<WCHAR> widestr(bufferlen + 1);
::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), &widestr[0], bufferlen);
// Ensure wide string is null terminated
widestr[bufferlen] = 0;
// no need to delete; handled by vector
Além disso, se você precisar trabalhar com strings largas para começar, poderá usar em std::wstring
vez de std::string
. Se você quiser trabalhar com o TCHAR
tipo do Windows , você pode usar std::basic_string<TCHAR>
. A conversão de std::wstring
para LPCWSTR
ou de std::basic_string<TCHAR>
para LPCTSTR
é apenas uma questão de ligar c_str
. É quando você muda entre ANSI e UTF-16 caracteres queMultiByteToWideChar
(e seu inverso WideCharToMultiByte
) entra em cena.
A conversão é simples:
std::string myString;
LPCSTR lpMyString = myString.c_str();
Uma coisa a ter cuidado aqui é que c_str não retorna uma cópia de myString, mas apenas um ponteiro para a string de caracteres que std :: string envolve. Se você quiser / precisar de uma cópia, você mesmo precisará fazer uma usando o strcpy.
A maneira mais fácil de converter a std::string
em a LPWSTR
é, em minha opinião:
std::string
em umstd::vector<wchar_t>
wchar_t
no vetor.std::vector<wchar_t>
tem um ctor modelado que terá dois iteradores, como os iteradores std::string.begin()
e .end()
. No wchar_t
entanto, isso converterá cada char em um . Isso só é válido se std::string
contiver ASCII ou Latin-1, devido à forma como os valores Unicode se assemelham aos valores Latin-1. Se contiver CP1252 ou caracteres de qualquer outra codificação, é mais complicado. Em seguida, você precisará converter os personagens.
std::wstring
?