Como converter std :: string em LPCSTR?

111

Como posso converter um std::stringpara LPCSTR? Além disso, como posso converter umstd::string para LPWSTR?

Estou totalmente confuso com estes LPCSTR LPSTR LPWSTReLPCWSTR .

São LPWSTRe LPCWSTRiguais?

Fofa
fonte

Respostas:

114

str.c_str()fornece um const char *, que é um LPCSTR(Ponteiro longo para STRing constante) - significa que é um ponteiro para uma 0string terminada de caracteres. Wsignifica string larga (composta de em wchar_tvez de char).

Lou franco
fonte
5
Menor ponto exigente: em x64, o LPCSTR seria um ponteiro de 64 bits para uma string terminada em nulo (constante).
Joel
154

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.

Nick Meyer
fonte
32

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::stringem 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::stringinstância e só será válido até a próxima modificação ou destruição da string.

Converter a std::stringem a LPWSTRé mais complicado. Querer um LPWSTRimplica que você precisa de um buffer modificável e também precisa ter certeza de que entende qual codificação de caracteres o std::stringestá usando. Se o std::stringconté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;
}
CB Bailey
fonte
18

Usando LPWSTRvocê pode alterar o conteúdo da string para onde ela aponta. Usando LPCWSTRvocê 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, LPWSTRvocê 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
}
Kirill V. Lyadvinsky
fonte
4

A MultiByteToWideCharresposta que Charles Bailey deu é a correta. Como LPCWSTRé apenas um typedef para const WCHAR*, widestrno código de exemplo ele pode ser usado sempre que um LPWSTRfor esperado ou onde um LPCWSTRfor 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::wstringvez de std::string. Se você quiser trabalhar com o TCHARtipo do Windows , você pode usar std::basic_string<TCHAR>. A conversão de std::wstringpara LPCWSTRou 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.

Joel
fonte
3

A conversão é simples:

std :: string str; LPCSTR lpcstr = str.c_str ();

Timbó
fonte
3

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.

Nick Haddad
fonte
1

A maneira mais fácil de converter a std::stringem a LPWSTRé, em minha opinião:

  1. Converta o std::stringem umstd::vector<wchar_t>
  2. Pegue o endereço do primeiro wchar_tno vetor.

std::vector<wchar_t>tem um ctor modelado que terá dois iteradores, como os iteradores std::string.begin()e .end(). No wchar_tentanto, isso converterá cada char em um . Isso só é válido se std::stringcontiver 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.

MSalters
fonte
Por que não usar std::wstring?
Timmmm
@Timmmm: C ++ 11 tornou a especificação mais rígida, já que as implementações não tiraram proveito das regras antigas, hoje isso estaria OK.
MSalters
1
std::string myString("SomeValue");
LPSTR lpSTR = const_cast<char*>(myString.c_str());

myString é a string de entrada e lpSTR é seu equivalente LPSTR .

Nani
fonte