Bagaimana cara mengonversi std :: string ke LPCSTR?

111

Bagaimana cara mengubah a std::stringmenjadi LPCSTR? Juga, bagaimana cara mengonversi a std::stringmenjadi LPWSTR?

Saya benar-benar bingung dengan ini LPCSTR LPSTR LPWSTRdan LPCWSTR.

Apakah LPWSTRdan LPCWSTRsama?

Imut
sumber

Jawaban:

114

str.c_str()memberi Anda a const char *, yang merupakan LPCSTR(Long Pointer ke Constant STRing) - artinya pointer ke 0string karakter yang diakhiri. WBerarti string lebar (terdiri dari wchar_tsebagai pengganti char).

Lou Franco
sumber
5
Titik pilih-pilih kecil: pada x64 LPCSTR akan menjadi penunjuk 64-bit ke string yang diakhiri dengan nol (konstan).
Yoel
154

Panggilan c_str()untuk mendapatkan const char *( LPCSTR) dari a std::string.

Semuanya atas nama:

LPSTR - (panjang) penunjuk ke string - char *

LPCSTR - (panjang) penunjuk ke string konstan - const char *

LPWSTR - Penunjuk (panjang) ke string Unicode (lebar) - wchar_t *

LPCWSTR - Penunjuk (panjang) ke string Unicode (lebar) konstan - const wchar_t *

LPTSTR - (panjang) pointer ke TCHAR (Unicode jika UNICODE didefinisikan, ANSI jika tidak) string - TCHAR *

LPCTSTR - (panjang) penunjuk ke string TCHAR konstan - const TCHAR *

Anda dapat mengabaikan bagian L (panjang) dari nama - itu peninggalan dari Windows 16-bit.

Nick Meyer
sumber
32

Ini adalah typedef yang ditentukan Microsoft yang sesuai dengan:

LPCSTR: penunjuk ke string const diakhiri null dari char

LPSTR: penunjuk ke string karakter yang diakhiri null dari char (seringkali buffer dilewatkan dan digunakan sebagai parameter 'keluaran')

LPCWSTR: penunjuk ke null yang diakhiri string dari const wchar_t

LPWSTR: pointer ke null diakhiri string wchar_t(seringkali buffer dilewatkan dan digunakan sebagai parameter 'keluaran')

Untuk "mengubah" a std::stringke LPCSTR tergantung pada konteks yang tepat tetapi biasanya panggilan .c_str()sudah cukup.

Ini bekerja.

void TakesString(LPCSTR param);

void f(const std::string& param)
{
    TakesString(param.c_str());
}

Perhatikan bahwa Anda tidak boleh mencoba melakukan sesuatu seperti ini.

LPCSTR GetString()
{
    std::string tmp("temporary");
    return tmp.c_str();
}

Buffer yang dikembalikan oleh .c_str()dimiliki oleh std::stringinstance dan hanya akan valid sampai string selanjutnya diubah atau dihancurkan.

Untuk mengubah a std::stringmenjadi a LPWSTRlebih rumit. Menginginkan an LPWSTRmenyiratkan bahwa Anda memerlukan buffer yang dapat dimodifikasi dan Anda juga perlu memastikan bahwa Anda memahami pengkodean karakter apa yang std::stringdigunakan. Jika std::stringberisi string menggunakan pengkodean default sistem (dengan asumsi windows, di sini), maka Anda dapat menemukan panjang buffer karakter lebar yang diperlukan dan melakukan transcoding menggunakanMultiByteToWideChar (fungsi Win32 API).

misalnya

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
sumber
18

Menggunakan LPWSTRAnda dapat mengubah konten string yang menunjuknya. Menggunakan LPCWSTRAnda tidak dapat mengubah konten string yang menunjuknya.

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();

LPWSTRhanyalah penunjuk ke string asli. Anda tidak boleh mengembalikannya dari fungsi menggunakan contoh di atas. Agar tidak bersifat sementara, LPWSTRAnda harus membuat salinan string asli di heap. Periksa contoh di bawah ini:

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
sumber
4

The MultiByteToWideCharjawaban yang Charles Bailey memberi adalah yang benar. Karena LPCWSTRhanya typedef untuk const WCHAR*, widestrdalam kode contoh ada dapat digunakan dimanapun yang LPWSTRdiharapkan atau yang LPCWSTRdiharapkan.

Satu std::vector<WCHAR>perubahan kecil akan digunakan sebagai pengganti array yang dikelola secara manual:

// 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

Juga, jika Anda perlu untuk bekerja dengan string lebar untuk memulainya, Anda dapat menggunakan std::wstringbukan std::string. Jika Anda ingin bekerja dengan TCHARtipe Windows , Anda dapat menggunakan std::basic_string<TCHAR>. Mengubah dari std::wstringmenjadi LPCWSTRatau dari std::basic_string<TCHAR>menjadi LPCTSTRhanyalah masalah panggilan c_str. Saat Anda mengubah antara karakter ANSI dan UTF-16 yang MultiByteToWideChar(dan kebalikannya WideCharToMultiByte) muncul di gambar.

Joel
sumber
3

Konversinya sederhana:

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

Timbo
sumber
3

Mengonversi itu sederhana:

std::string myString;

LPCSTR lpMyString = myString.c_str();

Satu hal yang harus diperhatikan di sini adalah bahwa c_str tidak mengembalikan salinan myString, tetapi hanya penunjuk ke string karakter yang dibungkus std :: string. Jika Anda ingin / membutuhkan salinan, Anda harus membuatnya sendiri menggunakan strcpy.

Nick Haddad
sumber
1

Cara termudah untuk mengubah a std::stringmenjadi a LPWSTRmenurut saya:

  1. Ubah std::stringmenjadistd::vector<wchar_t>
  2. Ambil alamat yang pertama wchar_tdi vektor.

std::vector<wchar_t>memiliki ctor template yang akan mengambil dua iterator, seperti the std::string.begin()dan .end()iterators. Ini akan mengubah setiap karakter menjadi a wchar_t. Itu hanya valid jika std::stringberisi ASCII atau Latin-1, karena cara nilai Unicode mirip dengan nilai Latin-1. Jika berisi CP1252 atau karakter dari pengkodean lain, ini lebih rumit. Anda kemudian harus mengonversi karakter.

MSalters
sumber
Mengapa tidak digunakan std::wstring?
Timmmm
@Timmmm: C ++ 11 memperketat spesifikasi karena implementasi tidak memanfaatkan aturan lama, hari ini tidak masalah.
MSalters
1
std::string myString("SomeValue");
LPSTR lpSTR = const_cast<char*>(myString.c_str());

myString adalah string input dan lpSTR adalah setara dengan LPSTR .

Nani
sumber